我正在积极学习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}}替换上述呼叫,则代码可以正常工作。
我该如何解决这个问题?
答案 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();
}
}
}