JPA合并只读字段
我们有最简单的CRUD任务,包括JPA 1.0和JAX-WS.
假设我们有一个实体Person. @Entity public class Person { @Id private String email; @OneToOne(fetch = FetchType.LAZY) @JoinColumn(insertable = false,updatable = false) private ReadOnly readOnly; @Column private String name; @XmlElement public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @XmlElement public Long getReadOnlyValue() { return readOnly.getValue(); } // more get and set methods } 这是场景. @Stateless @WebService public class PersonService { @PersistenceContext(name = "unit-name") private EntityManager entityManager; public Person create(Person person) { entityManager.persist(person); return person; } } 现在客户端尝试更新人员,这就是我,JPA显示其不一致的地方. public Person update(Person person) { Person existingPerson = entityManager.find(Person.class,person.getEmail()); // some logic with existingPerson // ... // At this point existingPerson.readOnly is not null and it can't be null // due to the database. // The field is not updatable. // Person object has readOnly field equal to null as it was not passed // via SOAP request. // And now we do merge. entityManager.merge(person); // At this point existingPerson.getReadOnlyValue() // will throw NullPointerException. // And it throws during marshalling. // It is because now existingPerson.readOnly == person.readOnly and thus null. // But it won't affect database anyhow because of (updatable = false) return existingPerson; } 为了避免这个问题,我需要为readOnly对象公开set,并在合并之前执行类似的操作. Person existingPerson = entityManager.find(Person.class,person.getEmail()); person.setReadOnlyObject(existingPerson.getReadOnlyObject()); // Arghhh! 我的问题: >这是一个功能还是只是 解决方法
我不知道,但我会说这是合并的预期行为.以下是在实体上调用merge时发生的情况: >现有实体在持久化上下文中加载(如果尚未存在) 这适用于简单的情况,但是如果你收到一个部分值对象(有些字段或关联设置为null)要合并,则不能正常工作:数据库中的空字段将被设置为null,这可能不是你想要的.
在这种情况下,您应该使用“手动合并”:使用find加载现有实体并通过复制新状态自行更新要更新的字段,让JPA检测更改并将其刷新到数据库. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |