我有类似的东西..
拥有多个座位的一个座位的汽车类。 Seat有一个子类LeatherSeat。
public class Car {
private Seat seat;
...
@ManyToOne(fetch = FetchType.LAZY)
public Seat getSeat() {
return seat;
}
...
}
@Entity
@Inheritance(strategy=InheritanceType.JOINED)
public class Seat {
private String id;
private String color;
}
@Entity
public class LeatherSeat extends Seat {
private String leatherType;
}
当我创建我的汽车并将我的汽车座椅设为LeatherSeat时,它会正确地保存在数据库上。当我想要获得我的Car(使用Criteria或Query列表)并且我读取getSeat()时,Seat始终只是一个座位,而不是一个LeatherSeat。我无法施放(例外),似乎必须通过id手动获取LeatherSeat。
这是使用JOINED继承类型的限制还是我遗漏了某些东西。如何将Seat作为LeatherSeat?
答案 0 :(得分:2)
在LAZY案例中,座位将是“代理”,在实例化汽车时实例化。那时,Hibernate不知道座位是否是皮革。
当您遍历该属性并且它被延迟加载时,Hibernate将知道Seat是皮革,但它不能回溯地更改代理的类。但是,所有数据都在那里。如果您已经覆盖任何方法,座位将作为LeatherSeat响应。
如果您确实需要将此对象强制转换为LeatherSeat,则可以使用http://docs.jboss.org/hibernate/orm/3.2/api/org/hibernate/engine/PersistenceContext.html#unproxy(java.lang.Object取消装箱代理
请参阅此博客,详细了解为什么代理将始终为Seat,而不是LeatherSeat:http://sessionfactory.blogspot.co.uk/2010/08/hacking-lazy-loaded-inheritance.html
这里简要介绍了Hibernate文档:http://docs.jboss.org/hibernate/core/3.3/reference/en/html/performance.html#performance-fetching-proxies
答案 1 :(得分:1)
看起来,如果你做一个懒惰的提取,就像你正在使用getSeat一样,你将只获得父级,而不是子级。我尝试了与FetchType.EAGER相同的示例,并且getSeat正确返回LeatherSeat。
我不确定为什么hibernate在获取EAGER时可以获得带有LeatherSeat的Car,但是当进行LAZY获取时,hibernate似乎无法获得它。好像有什么东西在那里被打破了。
在InheritanceType.JOINED上有关于鉴别器列的故障单,其中有关于此方案的点。 https://hibernate.onjira.com/browse/ANN-140但是票据被拒绝,表明hibernate太优雅了,不需要InheritanceType.JOINED的鉴别器。然而,它无法在延迟提取上正确返回子类。
然后这个票据https://hibernate.onjira.com/browse/HHH-271?focusedCommentId=44089#comment-44089更具体地针对这个问题,那里的答案是“我们怎么想知道什么子类可以获得懒惰的提取?”
这两张票都很旧,被拒绝了。对我来说似乎是一个问题。但是现在您必须更改为不同的继承类型或使用eager fetch类型,因为这是根据hibernate的设计。