Dom*_*nik 17 java hibernate jpa
我正在使用实体类观察一个非常奇怪的行为,并使用JPA(hibernate entitymanager 3.3.1.ga)加载此类的对象.Class有一个(嵌入)字段,在声明中初始化.该字段的setter实现了一个空检查(即在设置null值时会抛出异常).
...
@Entity
public class Participant extends BaseEntity implements Comparable<Participant> {
...
@Embedded
private AmsData amsData = new AmsData();
public void setAmsData(AmsData amsData) {
Checks.verifyArgNotNull(amsData, "amsdata");
this.amsData = amsData;
}
...
}
Run Code Online (Sandbox Code Playgroud)
当我使用JPA获取此对象时,如果db中没有嵌入对象中指定的字段的数据,则该字段为null.
...
public class ParticipantJpaDao implements ParticipantDao {
@PersistenceContext
private EntityManager em;
@Override
public Participant getParticipant(Long id) {
return em.find(Participant.class, id);
}
...
}
Run Code Online (Sandbox Code Playgroud)
我在字段上使用观察点调试了进程(应该在访问或修改字段时停止),并且在初始化字段时看到一个修改,但是当我从查找调用获得结果时,该字段为空.
任何人都可以解释一下,为什么会这样?如果数据库中没有嵌入对象字段的数据(除了在查找调用之后手动设置它),我如何确保该字段不为空.
Rob*_*ell 17
JPA规范没有明确说明如何处理一组表示可嵌入对象的列,这些列都是空的.它可以发出空引用或带有所有空字段的对象实例的信号.在这种情况下,Hibernate选择一个空引用,尽管其他JPA实现可能会选择更晚的引用.
永远不会调用你的setter的原因是因为Hibernate通过反射访问你的字段,绕过了你实现的setter.它这样做是因为您使用基于字段的访问而不是基于属性的访问.
乍得的答案将提供您正在寻找的功能,但有一点需要注意(见下文).
"...实体的持久状态由持久性提供程序运行时[1]通过JavaBeans样式属性访问器或实例变量访问.单一访问类型(字段或属性访问)适用于实体层次结构.使用时,将映射注释放置在实体类的持久字段或持久属性上将访问类型分别指定为基于字段或属性的访问..."[ejb3持久性规范]
因此,通过将注释向下移动到setter,您告诉JPA您希望使用基于属性的访问而不是基于字段的访问.但是,您应该知道,基于字段的访问 - 与您当前实现的一样 - 优先于基于属性的访问.有一些原因可以阻止基于属性的访问,但是有一个原因是你被迫为所有持久性实体字段添加getter和setter,但是你可能不希望那些相同的字段容易被外部客户端变异.换句话说,使用JPA的基于属性的访问会强迫您削弱实体的封装.
| 归档时间: |
|
| 查看次数: |
11082 次 |
| 最近记录: |