6

我被这个问题困住了。数据库模式是由其他人提供的,所以我不能简单地更改名称。我尝试在任何地方添加适当的注释,也许我遗漏了一些东西(很明显)?

这是我的完整映射(很多类),我将省略 getter/setter。

问题是当休眠试图获取所有List<ControlRuleAttrib> controlRuleAttribs

控制规则

@Entity
@Table(name = "CONTROL_RULE")
public class ControlRule implements Serializable {
 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 @Column(name = "CONTROL_RULE_ID")
 private Long id;
 @ManyToOne(fetch = FetchType.LAZY)
 @Cascade(CascadeType.ALL)
 @JoinColumn(name = "CONTROL_RULE_TYPE_ID")
 @ForeignKey(name = "CONTROL_RULE_TYPE_ID")
 private ControlRuleType controlRuleType;
 @Column(name = "JOB_NM")
 private String jobname;
 @Column(name = "LIBRARY_NM")
 private String libraryname;
 @Column(name = "TABLE_NM")
 private String tablename;
 @Column(name = "COLUMN_NM")
 private String columnname;

 @OneToMany(fetch = FetchType.LAZY)
 @Cascade(CascadeType.ALL)
 @JoinTable(name = "CONTROL_RULE_ATTRIB", joinColumns = {
  @JoinColumn(name = "CONTROL_RULE_ID", nullable = false, updatable = false)
 })
 private List < ControlRuleAttrib > controlRuleAttribs;
}

控制规则属性

@Table(name = "CONTROL_RULE_ATTRIB")
@Entity
public class ControlRuleAttrib {
 @EmbeddedId
 private ControlRuleAttribPK controlRuleAttribPK;

 @Column(name = "ATTRIBUTE_VALUE")
 private String attributeValue;
}

ControleRuleAttribPK 这里的问题是,是否有可能以某种方式从中获取ControlRuleAttribType实体ControlRuleAttrib?正如您在下面看到ControlRuleAttribTypeId的是ControleRuleAttribType. 我想得到整数的整个对象。

@Embeddable
public class ControlRuleAttribPK implements Serializable {
 @Column(name = "CONTROL_RULE_ID")
 private Long controlRuleId;

 @Column(name = "ATTRIBUTE_SEQ_NUM")
 private Integer attributeSeqNum;

 @Column(name = "CONTROL_RULE_ATTRIB_TYPE_ID")
 private Integer controlRuleAttribTypeId;
}

控制规则属性类型

@Entity
@Table(name = "CONTROL_RULE_ATTRIB_TYPE")
public class ControlRuleAttribType implements Serializable {
 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 @Column(name = "CONTROL_RULE_ATTRIB_TYPE_ID")
 private Integer id;
 @Column(name = "CONTROL_RULE_ATTRIB_TYPE_NM")
 private String typename;
 @Column(name = "CONTROL_RULE_ATTRIB_TYPE_DESC")
 private String typedesc;

 @ManyToOne(fetch = FetchType.LAZY)
 @Cascade(CascadeType.ALL)
 @JoinColumn(name = "CONTROL_RULE_TYPE_ID")
 @ForeignKey(name = "CONTROL_RULE_TYPE_ID")
 private ControlRuleType controlruletype;
}

控制规则类型

@Entity
@Table(name = "CONTROL_RULE_TYPE")
public class ControlRuleType implements Serializable {
 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 @Column(name = "CONTROL_RULE_TYPE_ID")
 private Integer id;
 @Column(name = "CONTROL_RULE_TYPE_NM")
 private String typename;
 @Column(name = "CONTROL_RULE_TYPE_DESC")
 private String typedesc;
}

编辑

这是堆栈跟踪:

https://gist.github.com/a30dd9ce534d96bb9a97

你会发现,它在这里失败了:

在 com.execon.controllers.main.MainPageController.getMainPage(MainPageController.java:33) [类:]

就是这样:

List<ControlRule> list = SessionFactoryUtils.openSession(
    sessionFactory ).createQuery( "from ControlRule" ).list();
System.out.println( list );

我添加的每个映射对象都有toString()这样声明的方法:

@Override
public String toString()
{
    String s = "ControlRule{";
    s += "id=" + id.toString();
    s += ", controlRuleType=" + controlRuleType;
    s += ", jobname='" + jobname + '\'';
    s += ", libraryname='" + libraryname + '\'';
    s += ", tablename='" + tablename + '\'';
    s += ", columnname='" + columnname + '\'';
    s += ", controlRuleAttribs=" + controlRuleAttribs;
    s += '}';
    return s;
}

和休眠请求:

https://gist.github.com/c8584113522757a4e0d8/4f31dc03e7e842eef693fa7ba928e19d27b3ca26

请帮忙 :)

编辑 2

好吧,在阅读了@Jens 的答案后,我对代码进行了一些更改。首先我按照你写的做了,它给出了错误:

org.hibernate.AnnotationException:从 com.execon.models.controlrules.ControlRule 引用 com.execon.models.controlrules.ControlRuleAttrib 的外键具有错误的列数。应该是 3

我想这是对的,因为我有复合主键。

然后我这样尝试:

@OneToMany(fetch = FetchType.LAZY)
@Cascade(CascadeType.ALL)
@JoinTable(name = "CONTROL_RULE_ATTRIB",
        joinColumns = {
                @JoinColumn(name = "CONTROL_RULE_ID", nullable = false, updatable = false)
        },
        inverseJoinColumns = {
                @JoinColumn(name = "CONTROL_RULE_ID", nullable = false, updatable = false),
                @JoinColumn(name = "CONTROL_RULE_ATTRIB_TYPE_ID", nullable = false, updatable = false),
                @JoinColumn(name = "ATTRIBUTE_SEQ_NUM", nullable = false, updatable = false)
        })
private List<ControlRuleAttrib> controlRuleAttribs;

非常接近,但它给了我以下例外:

集合映射中的重复列..

所以最后我删除了

joinColumns = 
{
    @JoinColumn(name = "CONTROL_RULE_ID", nullable = false, updatable = false)
}

除了当我尝试到达集合时,所有的东西都编译了,Hibernate 正在执行以下查询:

https://gist.github.com/c88684392f0b7a62bea5

最后一行是controlrul0_.CONTROL_RULE_CONTROL_RULE_ID=?while it should be controlrul0_.CONTROL_RULE_ID=?

无论如何我可以让它工作吗?:/

4

3 回答 3

3

在过去几个小时为此苦苦挣扎之后,我终于使它在我的项目中工作。我做的是这样的:

控制规则

@OneToMany(fetch = FetchType.LAZY, mappedBy = "controlRuleAttribPK.controlRuleId")
@Cascade(CascadeType.ALL)
private List<ControlRuleAttrib> controlRuleAttribs;

基本上指出集合应该使用来自复合主键的 controlRuleId。到目前为止,它工作得很好!

于 2012-07-11T12:13:01.320 回答
0

我不清楚哪个标识符太长,但我可以建议您可以尝试将@Id带注释的字段类型从更改IntegerLong。获得有关您的问题的一些详细信息(堆栈跟踪等)会很棒。

于 2012-07-10T13:30:23.133 回答
0

问题是列

CONTROL_RULE_ATTRIB.controlRuleAttribs_CONTROL_RULE_ATTRIB_TYPE_ID

太长了,它不可能存在于您的数据库中。我在问题中没有看到任何提示它实际上是如何命名的,但我假设正确的名称是

CONTROL_RULE_ATTRIB.CONTROL_RULE_ATTRIB_TYPE_ID

所以问题是:为什么hibernate试图访问这个列。它所在的表是一个映射表,在休眠中映射为:

@OneToMany(fetch = FetchType.LAZY)
@Cascade(CascadeType.ALL)
@JoinTable(name = "CONTROL_RULE_ATTRIB", joinColumns = {@JoinColumn(name = "CONTROL_RULE_ID", nullable = false, updatable = false)})
private List<ControlRuleAttrib> controlRuleAttribs;

如果您查看 @JoinTable 注释,您会注意到它定义了使用时的表名和连接列。但是一个映射表有两组连接列。未指定第二个。因此,您配置的 NamingStrategy 或者如果您没有配置任何默认值,则使用。只需使用属性 inverseJoinColumns 指定另一组连接列,一切都应该没问题。

完整的注释应如下所示:

@JoinTable(name = "CONTROL_RULE_ATTRIB", joinColumns = {@JoinColumn(name = "CONTROL_RULE_ID", nullable = false, updatable = false)}, inverseJoinColumns = {@JoinColumn(name = "CONTROL_RULE_ATTRIB_TYPE_ID")})

注意:我不知道您是否还需要该列上的任何可空、可更新的东西。

另请参阅JoinTable 注释的文档

于 2012-07-10T19:43:11.730 回答