Hibernate和@JoinFormula:org.hibernate.mapping.Formula无法强制转换为org.hibernate.mapping.Column
我正在尝试为旧的数据库模式编写一个hibernate适配器。 此架构没有专用的id列,但使用大约三个其他列来连接数据。
在某些表格中,我需要使用合并。 这是我到目前为止提出的:
关于定义:
- 汽车可以具有由汽车用户或汽车的用户组分配的元件。
- 如果FORIGN_ELEMENT包含用户名,则定义为’u’
- 如果FORIGN_ELEMENT包含组的名称,则定义为’g’
- 这也意味着,一个表(CAR_TO_ELEMENT)被误用于将汽车映射到元素和汽车组到元素。 我定义了一个超类CarElement和子类CarUserElement和CarGroupElement。
- state是“active”或无趣的字符串
- 我在其他地方设定了定义和陈述,我们不需要担心这一点。
- 在连接表上使用DEP_NR。 如果为零,请使用USR_DEP_NR。 我在本机SQL中成功地使用
COALESCE(NULLIF())
并且希望在Hibernate中使用Pojos实现相同的function。
好的,我们在这里使用代码:
@Entity @Table(name="CAR") public class Car extends TableEntry implements Serializable { @Id @Column(name="DEP_NR") private int depnr; @Id @Column(name="USER_NAME") @Type(type="TrimmedString") private String username; @ManyToOne(fetch = FetchType.EAGER, targetEntity=CarGroup.class) @JoinColumns(value={ @JoinColumn(name="GROUP_NAME"), @JoinColumn(name="DEP_NR"), @JoinColumn(name="state"), }) private CarGroup group; @OneToMany(fetch=FetchType.EAGER, targetEntity=CarUserElement.class, mappedBy="car") private Set elements; }
@Entity @Table(name="CAR_GROUP") public class CarGroup extends TableEntry implements Serializable { @Id @Column(name="DEP_NR") private int depnr; @Id @Column(name="GROUP_NAME") @Type(type="TrimmedString") private String group; @ManyToOne(fetch = FetchType.EAGER, targetEntity=Car.class) @JoinColumns(value={ @JoinColumn(name="GROUP_NAME"), @JoinColumn(name="DEP_NR"), @JoinColumn(name="state"), }) private Set cars; @OneToMany(fetch=FetchType.EAGER, targetEntity=CarGroupElement.class, mappedBy="car") private Set elements; }
@MappedSuperclass public class CarElement extends TableEntry { @Id @ManyToOne(fetch = FetchType.EAGER, targetEntity=Element.class) @JoinColumns(value={ @JoinColumn(name="ELEMENT_NAME"), @JoinColumn(name="state"), }) private Element element; }
@Entity @Table(name="CAR_TO_ELEMENT") public class CarUserElement extends CarElement { @Id @Column(name="DEFINITION") private char definition; @Id @ManyToOne(fetch = FetchType.LAZY) @JoinColumnsOrFormulas(value = { @JoinColumnOrFormula(formula=@JoinFormula(value="COALESCE(NULLIF(DEP_NR, 0), USR_DEP_NR)", referencedColumnName="DEP_NR")), @JoinColumnOrFormula(column=@JoinColumn(name="FORIGN_ELEMENT", referencedColumnName="USER_NAME")), @JoinColumnOrFormula(column=@JoinColumn(name="STATE", referencedColumnName="STATE")) }) private Car car; }
@Entity @Table(name="CAR_TO_ELEMENT") public class CarGroupElement extends CarElement { @Id @Column(name="DEFINITION") private char definition; @Id @ManyToOne(fetch = FetchType.LAZY) @JoinColumnsOrFormulas(value = { @JoinColumnOrFormula(formula=@JoinFormula(value="COALESCE(NULLIF(DEP_NR, 0), USR_DEP_NR)", referencedColumnName="DEP_NR")), @JoinColumnOrFormula(column=@JoinColumn(name="FORIGN_ELEMENT", referencedColumnName="GROUP_NAME")), @JoinColumnOrFormula(column=@JoinColumn(name="STATE", referencedColumnName="STATE")) }) private Car car; }
我尝试了所有可用的hibernate版本(从3.5.1 [带@JoinColumnsOrFormulas
第一个版本]到4.xx),但我总是得到这个错误:
Exception in thread "main" java.lang.ClassCastException: org.hibernate.mapping.Formula cannot be cast to org.hibernate.mapping.Column at org.hibernate.cfg.annotations.TableBinder.bindFk(TableBinder.java:351) at org.hibernate.cfg.annotations.CollectionBinder.bindCollectionSecondPass(CollectionBinder.java:1338) at org.hibernate.cfg.annotations.CollectionBinder.bindOneToManySecondPass(CollectionBinder.java:791) at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:719) at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:668) at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:66) at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1597) at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1355) at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1737) at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1788)
其他hibernate用户似乎也有同样的问题:他们无法使用任何版本,请参阅此主题和其他stackoverflow问题: https : //forum.hibernate.org/viewtopic.php? f = 1& t = 1010559
为了更完整,这是我的TrimmedString类: https ://forum.hibernate.org/viewtopic.php ? p = 2191674 & sid = 049b85950db50a8bd145f9dac49a5f6e #p2191674
提前致谢!
PS:只使用一个DEP-NR-Column(即只使用@JoinColumns的DEP_NR 或 USR_DEP_NR)就可以加入这三个colulmns。 但我需要这个coalesce(nullif())
。
暂时加入公式在Hibernate中非常脆弱; 我总是很难让他们正常工作。
经常帮助我的解决方法是创建数据库视图,这些视图暴露了正确的列(包括原始表中不存在的外键)。 然后我使用Hibernate / JPA映射分类将实体映射到视图。
有时在使用此类实体时生成的SQL中存在冗余连接,但数据库在大多数情况下会优化此类查询,以便执行计划无论如何都是最佳的。
另一种方法可能是使用@Subselect
,它是某种Hibernate视图,但我希望它们的性能低于经典的数据库视图。
我遇到了类似的问题,似乎问题是你在@Id中使用@Formula。 Hibernate希望Ids可以插入,而Formulas是只读的。
在我的情况下,我能够通过自己创建单独的列Id属性并使连接对象成为单独的属性来解决该问题。 我不知道这是否适用于您的情况,因为您在公式中使用了两个不同的列,但如果是这样,您的代码可能如下所示:
@Entity @Table(name="CAR_TO_ELEMENT") public class CarUserElement extends CarElement { @Id @Column(name="DEFINITION") private char definition; @Id @Column(name="DEP_NR") private Integer depNr; @Id @Column(name="USR_DEP_NR") private Integer usrDepNr; @Id @Column(name="FORIGN_ELEMENT") private String userName; @Id @Column(name="STATE") private String state; @ManyToOne(fetch = FetchType.LAZY) @JoinColumnsOrFormulas(value = { @JoinColumnOrFormula(formula=@JoinFormula(value="COALESCE(NULLIF(DEP_NR, 0), USR_DEP_NR)", referencedColumnName="DEP_NR")), @JoinColumnOrFormula(column=@JoinColumn(name="FORIGN_ELEMENT", referencedColumnName="USER_NAME", insertable = false, updatable = false)), @JoinColumnOrFormula(column=@JoinColumn(name="STATE", referencedColumnName="STATE", insertable = false, updatable = false)) }) private Car car; }
我也遇到了强制转换exception,我正在使用Hibernate 5.x.
直到Hibernate花时间来解决这个问题,我发现虽然这个人的方法可能不是最干净的(他甚至可以避免这个事实!),但它确实有效。
您只需要将@Column映射(和get / set方法)添加到返回null的关联表对象中,并在填充关系数据时手动设置值。 简单但有效!
- 如何在Java Hibernate应用程序中修复java.lang.ArrayIndexOutOfBoundsException
- 如何在hibernate中的多对一映射上定义反级联删除
- Hibernate HQL Join Query DOT节点没有左侧
- Jersey:com.sun.jersey.spi.inject.Errors $ ErrorMessagesException
- 什么是Hibernate中的级联?
- Hibernate的会话线程安全吗?
- Eclipse:添加javadoc
- 如何使用带有Oracle 10g方言的Hibernate使用JPA生成我的id?
- PostgreSQL串行类型的Hibernate注释