2011-10-05 93 views
3

在我的应用程序中,我连接到一个websocket。 套接字发送JSON数据。当它变得可用时,我在不同的工作中处理它。在每项工作中,我都将JSON转换为带有GSON的模型对象。有3种类型的模型,都是独立的,并且在MappedSuper类中有一个共同的时间戳字段。他们没有一个明确的字段。我在模型上调用保存,并在1000次中的1次中抛出“PersistentObjectException:传递给持久化的分离实体”。PersistentObjectException:传递给persist的分离实体

从启动作业连接到WebSocket调用多个作业。我正在使用的库为每个传入消息创建一个不同的线程。然后在保存到数据库之前将线程转换为作业。我这样做,因为否则另一个PersistentObjectException抛出有关将ID从1更改为2或类似的东西,如果我允许原始线程调用保存。

我还有另一个同时访问数据库的作业。什么可能是错的?

@Override 
public void onMessage(final WebSocketMessage message){ 
     new Job() { 
      @Override 
      public void doJob() { 
       processMessage(message.getText()); 
      } 
     }.now(); 

} 

public void processMessage(String message) { 
     Appointment appointment = new Gson().fromJson(message, Appointment.class); 
     appointment.save(); 
} 

@Entity 
public class Appointment extends CalendarEvent { 
     private String owner; 
} 

@MappedSuperclass 
public abstract class CalendarEvent extends Model { 
     private long timestamp; 
} 

编辑:添加了一些代码示例

+0

如何识别模型对象?放置在@Id字段中的值是否可能不是唯一的? – millhouse

+0

每个Model类都有一个id字段,即null。我的课程扩展了模型。他们本身并不声明id字段。 – siamii

+0

顺便说一句,我真的不明白这个消息的意思。 “独立实体通过坚持”意味着什么? (我不是母语的人) – siamii

回答

0

我发现此解决方法现在可以工作。也许这与Gson和Jpa如何互动有关。不确定...

public void processMessage(String message) { 
     Appointment appointment = new Gson().fromJson(message, Appointment.class); 
     //recreate appointment 
     appointment = new Appointment(appointment); 
     appointment.save(); } 
+0

必须是。多么奇怪。我假设你的'Appointment'拷贝构造函数总是显式地将'id'设置为'null',从而确保它被认为是EntityManager的“新”。 – millhouse

5

基本上这意味着EntityManager不会跟踪他们的任何更多:This is a good overview如果你没有明确地要求它是奇怪的,它们会被认为是分离的。但解决方法可能是在您的DAO方法和merge这些奇怪的情况下使用“防御”的方法;即:

public void save (Model possiblyDetachedModel) { 

    if (entityManager.contains(possiblyDetachedModel)) { 
     entityManager.merge(possiblyDetachedModel); 
    } else { 
     entityManager.persist(possiblyDetachedModel); 
    } 
} 

我并不特别喜欢它,因为它不应该需要,当你persist荷兰国际集团全新的对象来完成。这可能是值得一些登录(或尽可能调试)“merge”分支,并真正检查那些流氓物体 - 我敢肯定EntityManager只能使用@Id字段作为检测机制...

+0

感谢您的链接。我发现了一种解决方法,目前似乎有效... – siamii

相关问题