【发布时间】:2011-12-04 03:25:25
【问题描述】:
我正在尝试在我的 Seam/Hibernate/JPA 应用程序中利用 EntityListener 对象和回调方法。我在 JBoss 5.1 上使用 Seam 2.2 管理的持久性上下文,在后端使用 PostgreSQL 9.1。我声明了以下实体:
@Entity(name = "TestEntity")
@EntityListeners(TestCallback.class)
@Table(name = "tbl_test")
public class TestEntity implements Serializable {
private static final long serialVersionUID = 2016897066783042092L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "xxx")
@SequenceGenerator(name = "xxx", sequenceName = "xxx")
@Index(name = "xxx")
@DocumentId
private Long id = null;
@Column
private String test = null;
...
}
以及以下 EntityListener 回调类:
public class TestCallback {
/**
* Logger for this class
*/
private Log logger = null;
public TestCallback() {
logger = Logging.getLog(TestCallback.class);
}
@PrePersist
public void prePersist(TestEntity e) {
logger.debug("prePersist(TestEntity) - start"); //$NON-NLS-1$
logger.debug("prePersist(TestEntity) - end"); //$NON-NLS-1$
}
@PostPersist
public void postPersist(TestEntity e) {
logger.debug("postPersist(TestEntity) - start"); //$NON-NLS-1$
logger.debug("postPersist(TestEntity) - end"); //$NON-NLS-1$
}
@PostLoad
public void postLoad(TestEntity e) {
logger.debug("postLoad(TestEntity) - start"); //$NON-NLS-1$
logger.debug("postLoad(TestEntity) - end"); //$NON-NLS-1$
}
@PreUpdate
public void preUpdate(TestEntity e) {
logger.debug("preUpdate(TestEntity) - start"); //$NON-NLS-1$
logger.debug("preUpdate(TestEntity) - end"); //$NON-NLS-1$
}
@PostUpdate
public void postUpdate(TestEntity e) {
logger.debug("postUpdate(TestEntity) - start"); //$NON-NLS-1$
logger.debug("postUpdate(TestEntity) - end"); //$NON-NLS-1$
}
@PreRemove
public void preRemove(TestEntity e) {
logger.debug("preRemove(TestEntity) - start"); //$NON-NLS-1$
logger.debug("preRemove(TestEntity) - end"); //$NON-NLS-1$
}
@PostRemove
public void postRemove(TestEntity e) {
logger.debug("postRemove(TestEntity) - start"); //$NON-NLS-1$
logger.debug("postRemove(TestEntity) - end"); //$NON-NLS-1$
}
}
但是,当我运行我的测试时,我并没有看到我的所有回调方法都像我预期的那样被调用。我已经对以下场景进行了测试:
- 保留新项目
- 更新现有项目
- 加载项目
- 删除项目
但是,我看到的唯一回调是:
@PrePersist@PreRemove@PostLoad@PreUpdate
剩余的回调没有按预期执行。这是正常行为吗?我只是误会了吗?这是否与 Seam 管理事务的方式有关?或者,我只是没有做对吗?
如果您能提供任何帮助,我将不胜感激。
编辑:根据要求,这是我正在调用的确切代码和我收到的输出:
测试 1:
public void runTest() {
logger.debug("runTest() - start"); //$NON-NLS-1$
TestEntity e = new TestEntity();
e.setTest("XXX");
this.entityManager.persist(e);
this.entityManager.flush();
this.entityManager.clear();
logger.debug("runTest() - end"); //$NON-NLS-1$
}
输出 1:
12:27:56,307 INFO [STDOUT] 29735 DEBUG myapp.test.web.actions.test.TestAction - - runTest() - start
12:27:56,312 INFO [STDOUT] 29740 DEBUG myapp.test.entities.TestCallback - - prePersist(TestEntity) - start
12:27:56,312 INFO [STDOUT] 29740 DEBUG myapp.test.entities.TestCallback - - prePersist(TestEntity) - end
12:27:56,347 INFO [STDOUT] 29775 DEBUG myapp.test.web.actions.test.TestAction - - runTest() - end
测试 2:
public void runTest2() {
logger.debug("runTest2() - start"); //$NON-NLS-1$
String sql = "SELECT DISTINCT t FROM TestEntity t";
Query q = this.entityManager.createQuery(sql);
List<TestEntity> l = q.getResultList();
for (int i = 0; i < l.size(); i++) {
String x = l.get(i).getTest();
logger.debug("runTest2() - String x=" + x); //$NON-NLS-1$
}
logger.debug("runTest2() - end"); //$NON-NLS-1$
}
输出 2:
12:28:36,964 INFO [STDOUT] 70392 DEBUG myapp.test.web.actions.test.TestAction - - runTest2() - start
12:28:36,982 INFO [STDOUT] 70410 DEBUG myapp.test.entities.TestCallback - - postLoad(TestEntity) - start
12:28:36,982 INFO [STDOUT] 70410 DEBUG myapp.test.entities.TestCallback - - postLoad(TestEntity) - end
12:28:36,982 INFO [STDOUT] 70410 DEBUG myapp.test.web.actions.test.TestAction - - runTest2() - String x=XXX
12:28:36,983 INFO [STDOUT] 70411 DEBUG myapp.test.web.actions.test.TestAction - - runTest2() - end
测试 3:
public void runTest3() {
logger.debug("runTest3() - start"); //$NON-NLS-1$
String sql = "SELECT DISTINCT t FROM TestEntity t";
Query q = this.entityManager.createQuery(sql);
List<TestEntity> l = q.getResultList();
for (int i = 0; i < l.size(); i++) {
l.get(i).setTest("YYY" + System.currentTimeMillis());
this.entityManager.persist(l.get(i));
}
this.entityManager.flush();
this.entityManager.clear();
Random rand = new SecureRandom();
q = this.entityManager.createQuery(sql);
l = q.getResultList();
for (int i = 0; i < l.size(); i++) {
this.entityManager.remove(l.get(i));
}
this.entityManager.flush();
this.entityManager.clear();
logger.debug("runTest3() - end"); //$NON-NLS-1$
}
输出 3:
12:30:00,404 INFO [STDOUT] 153832 DEBUG myapp.test.web.actions.test.TestAction - - runTest3() - start
12:30:00,407 INFO [STDOUT] 153835 DEBUG myapp.test.entities.TestCallback - - postLoad(TestEntity) - start
12:30:00,407 INFO [STDOUT] 153835 DEBUG myapp.test.entities.TestCallback - - postLoad(TestEntity) - end
12:30:00,408 INFO [STDOUT] 153836 DEBUG myapp.test.entities.TestCallback - - preUpdate(TestEntity) - start
12:30:00,408 INFO [STDOUT] 153836 DEBUG myapp.test.entities.TestCallback - - preUpdate(TestEntity) - end
12:30:00,410 INFO [STDOUT] 153838 DEBUG myapp.test.entities.TestCallback - - postLoad(TestEntity) - start
12:30:00,411 INFO [STDOUT] 153839 DEBUG myapp.test.entities.TestCallback - - postLoad(TestEntity) - end
12:30:00,414 INFO [STDOUT] 153842 DEBUG myapp.test.entities.TestCallback - - preRemove(TestEntity) - start
12:30:00,414 INFO [STDOUT] 153842 DEBUG myapp.test.entities.TestCallback - - preRemove(TestEntity) - end
12:30:00,453 INFO [STDOUT] 153881 DEBUG myapp.test.web.actions.test.TestAction - - runTest3() - end
【问题讨论】:
-
请看我的回答,我已经更新了。我希望它有帮助!而且,如果您让我说一点:下次您更新答案时,请对答案发表评论,谁的所有者似乎对您的问题感兴趣。我之所以这么说,是因为我没有收到任何关于您已更新问题的通知(我已手动检查!:)。提前致谢!
-
如何注入你的 entityManager?包含 runTest 方法的类是否是接缝组件(使用 @Name 注释)?您也可以发布您的 components.xml 文件吗?我已经非常努力地重现了您的问题,但直到现在都没有运气。
-
我用标准的@In EntityManager entityManager 注入我的entitymanager;宣言。我的测试类是带有@Name("testAction") 的Seam 组件。 runTest*() 方法未声明为 @Transactional 或任何东西。这真的是一个非常简单的用例,所以我不知道为什么它不起作用。
标签: hibernate jpa callback seam entitylisteners