我遇到了JPA的问题。我有三个实体;第一个(事件)工作正常。我只提供标题:
@Entity
@EntityListeners({EventSupervisionListener.class})
public class Event extends Exportable {
// Some code
第二个扩展第一个并实现一个接口。这个效果不好。我可以持久保存新实体,但更新方法不起作用。
@Entity
public class RemoteEvent extends Event implements RemoteEntity {
@ManyToOne(optional=false)
private Remote net;
@Override
public Remote getRemote() {
return cellnet;
}
@Override
public void setRemoteCellNet(Remote net) {
this.net= net;
}
}
最后是远程实体,它也可以正常工作:
@Entity
@EntityListeners({RemoteListener.class})
public class Remote extends Device {
@ManyToOne(fetch= FetchType.EAGER, optional=true, cascade= CascadeType.ALL)
private RemoteArea remoteRootArea;
// A lots of contain but no reference with RemoteEvent or Event
对于更新,我有一个简单的方法:
// Get a event object :
RemoteEvent event = getEvent();
em.find(RemoteEvent.class, event.getId());
// Event is find (test with em.contain).
event.setName("test");
这不起作用;我不明白为什么......
感谢您的帮助
[经过一些研究后编辑新内容]
我已经简化了问题并专注于创建错误的方法。我有这个简单的层次结构:
@MappedSuperclass
public abstract class Exportable implements Serializable, UUIDOwner {
@Entity
@EntityListeners({EventSupervisionListener.class})
public class Event extends Exportable {
@Entity
public class RemoteEvent extends Event{
// This entity do nothing except extend Event.
问题似乎来自Event的这一部分,在调试模式下我可以到达@postLoad方法,但onUpdate永远不会调用。我可以通过评论json来绕过这个问题 loadImageGroup方法的一部分。
@Lob
private String images;
@ExtJsSerialize
private transient List<EventImageGroup> imageGroupList = new ArrayList<EventImageGroup>();
@PreUpdate
@PrePersist
private void saveImageGroups() {
JSONArray json = new JSONArray();
for (EventImageGroup imgGroup : imageGroupList) {
json.put(imgGroup.toJson());
}
images = json.toString();
}
@PostLoad
private void loadImageGroups() {
try
{
imageGroupList.clear();
// If i comment this instruction the code working fine.
// There are no exception rise.
JSONArray json = new JSONArray(images);
for (int i = 0; i < json.length(); ++i) {
imageGroupList.add(new EventImageGroup(json.getJSONObject(i)));
}
}
catch (JSONException ex) {
Logger.getLogger(Event1.class.getName()).log(Level.SEVERE, null, ex);
}
}
我确切地说,除了dtype之外,我在事件对象和remoteEvent的数据库中具有完全相同的值。
我无法理解为什么延伸而没有任何改变会导致问题......
由于
答案 0 :(得分:1)
这是因为简单地调用find()
并未标记您的实例event
已管理:您在该实例上所做的任何更改都不会被您的JPA提供程序跟踪/识别。为了解决这个问题,您应该对返回的实体进行更改:
// Get a event object :
RemoteEvent event = getEvent();
RemoveEvent eventDb = em.find(RemoveEvent.class, event.getId());
eventDb.setName("test");//note here the returned instance is used
//DO NOT FORGET TO COMMIT if necessary