我正在做一个项目,并且要管理一个“怪异”的映射。 没关系,这是结构:
元素由一个由cmpcode,elmlevel和代码组成的单个FK组成
发票由cmpcode,element2(这是2级元素,具有相同的cmpcode),element3(这是3级元素,具有相同的cmpcode)组成
所以表INVOICE有4列
ID
CMPCODE
EL2(具有相同CMPCODE的2级元素的代码)
EL3(具有相同CMPCODE的3级元素的代码)
我对Invoice.java类的映射是:
@Id
private Integer id;
@ManyToOne
@JoinColumn(name = "CMPCODE")
private Company company;
// This one does the mapping to Element, by forcing ELMLEVEL at 2, and using CMPCODE and EL2 for the rest of the mapping
@ManyToOne
@JoinColumnsOrFormulas({ @JoinColumnOrFormula(formula = @JoinFormula(value = "2", referencedColumnName = "ELMLEVEL")),
@JoinColumnOrFormula(column = @JoinColumn(name = "CMPCODE", referencedColumnName = "CMPCODE", insertable = false, updatable = false)),
@JoinColumnOrFormula(column = @JoinColumn(name = "EL2", referencedColumnName = "CODE")) })
private Element element2;
// This on is used to be able to set el2 (because we can't in the property above)
private String el2;
@ManyToOne
@JoinColumnsOrFormulas({ @JoinColumnOrFormula(formula = @JoinFormula(value = "3", referencedColumnName = "ELMLEVEL")),
@JoinColumnOrFormula(column = @JoinColumn(name = "CMPCODE", referencedColumnName = "CMPCODE", insertable = false, updatable = false)),
@JoinColumnOrFormula(column = @JoinColumn(name = "EL3", referencedColumnName = "CODE")) })
private Element element3;
private String el3;
如果我进行单个查询,则可以正常工作。
如果我使用分页进行查询,则生成的查询将引发不明确的列查询。 为什么?
因为单个查询是:
SELECT ID, CMPCODE, ELMLEVEL_1, CMPCODE_1, EL2_1, EL2_1, ELMLEVEL_2, CMPCODE_2, EL3_1, EL3_1 from INVOICE
如您所见,EL2_1有2倍,因为它在2个属性中,一个是String,另一个是Element。
对于单个查询,没有问题。
但是,现在,我们进行分页查询:
select * from (SELECT ID, CMPCODE, ELMLEVEL_1, CMPCODE_1, EL2_1, EL2_1, ELMLEVEL_2, CMPCODE_2, EL3_1, EL3_1 from INVOICE) where rownum<10
抛出了模棱两可的错误。
我已经坚持了三天。 我该怎么办?
如果删除el2字符串,我将无法再对其进行更新(由于可插入/可更新的false)。
如果我删除了insertable / updatable false,则重复出现列异常。
注意:我已经简化了模型,但是将element2改为element8
答案 0 :(得分:0)
我刚刚找到了带有Hibernate的小型“ hack”解决方案。 我已经将@JoinColumn替换为CMPCODE,以实现完全相同的@JoinFormula。 但是,有了这个,我可以删除第二个元素作为字符串,以及可更新/可插入的标志。 Hibernate似乎对此很满意。
// This one does the mapping to Element, by forcing ELMLEVEL at 2, and using CMPCODE and EL2 for the rest of the mapping
@ManyToOne
@JoinColumnsOrFormulas({ @JoinColumnOrFormula(formula = @JoinFormula(value = "2", referencedColumnName = "ELMLEVEL")),
@JoinColumnOrFormula(formula = @JoinFormula(name = "CMPCODE", referencedColumnName = "CMPCODE", insertable = false, updatable = false)),
@JoinColumnOrFormula(column = @JoinColumn(name = "EL2", referencedColumnName = "CODE")) })
private Element element2;