EJB和JPA - 具有多个EJB的持久化对象

时间:2014-05-26 20:57:22

标签: java jpa ejb entitymanager

我正在积极学习JPA和EJB,我遇到了以下情况:我有一个EJB(名为SecondController),它实现了一个持久化实体的方法。我们称之为SecondEntity。要求当实体被持久化时,其字段dateInserted被设置为当前日期(实际上,要求可能更复杂 - 我想知道概念是否正常或者我是否完全在错误的方向)。

现在我定义一个新实体 - 让我们称之为FirstEntity - 其中包含SecondEntity作为属性。我实现了另一个EJB,它实现了一个持久化FirstEntity的方法 - 因此每次FirstEntity持久化时,SecondEntity也必须保持不变。我知道我可以在@ManyToOne(optional = false, cascade = CascadeType.PERSIST)中的secondEntity属性上使用FirstEntity(这会自动保留)。但请记住,有一个dateInserted要求,逻辑已经实现。我们的想法是重用已经实现的方法,通过将SecondEntity注入SecondController来保留FirstController中的@Entity public class SecondEntity implements Serializable { } @Entity public class FirstEntity implements Serializable { @JoinColumn(name = "second_id", referencedColumnName = "second_id") @ManyToOne(optional = false) private SecondEntity secondEntity; } @Stateless public class SecondController implements Serializable { @PersistenceUnit(name = "PU") private EntityManagerFactory emf; public SecondController() { } public void create(SecondEntity secondEntity) { EntityManager em = emf.createEntityManager(); try { secondEntity.setDateInserted(new Date(System.currentTimeMillis())); em.persist(secondEntity); } finally { em.close(); } } } @Stateless public class FirstController implements Serializable { @PersistenceUnit(name = "PU") private EntityManagerFactory emf; @EJB private SecondController secondController; public FirstController() { } public void create(FirstEntity firstEntity) { EntityManager em = emf.createEntityManager(); try { secondController.create(firstEntity.getSecondEntity()); em.persist(firstEntity); } finally { em.close(); } } }

secondController.create(firstEntity.getSecondEntity())

上面的示例代码的要点是调用SecondEntity。这可以,还是被认为是一种不好的做法?我的应用程序中有两个这样的案例,其中一个是作品(null是可选的 - 可以是SecondEntity),而一个不是(null是强制性的 - 不能是em.persist(firstEntity) )。代码在em.persist(firstEntity.getSecondEntity)失败时说:

  

java.lang.IllegalStateException:在同步过程中,通过未标记为cascade的关系找到了一个新对象PERSIST

如果我用{{1}}替换上述呼叫,则代码可以正常工作。

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

您不应该在EJB中设置dateInserted字段。在PrePersist event hook中执行此操作。这样,持久性提供程序将确保在持久化实体之前始终自动调用钩子。然后你可以让persist从父实体级联到另一个(@ManyToOne(optional = false, cascade = CascadeType.PERSIST))。

@Entity
public class SecondEntity implements Serializable {
    @PrePersist
    public void prePersist() {
        if (dateInserted == null) {
            dateInserted = new Date();
        }
    }
}