- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我在数据库中出现双重插入的奇怪错误。我有以下类(class):
我将问题放在一个 junit 测试中(我使用的是嵌入式 Glassfish):
@Test
public void test() throws NamingException {
Dataset<TestEntity> dataset = this.lookupBy(DatasetBean.class);
Assert.assertNotNull(dataset);
TestEntity t = new TestEntity();
t.setName(UUID.randomUUID().toString());
dataset.insert(t);
System.out.println("end");
}
测试流程如下:
获取 Dataset 对象后,我尝试插入 TestEntity 对象
@无国籍@EJB(name = "...", beanInterface = Dataset.class)公共(public)类 DatasetBean 实现数据集 {
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
private EntityManager entityManager;
@Override
public void insert(T entidade) {
LOG.info("Inserting: " + entidade);
entityManager.persist(entidade);
}
//...
使用 DatasetFactory,我尝试在 TestEntity 的 @PostPersist 方法中插入审计实体
公共(public)类数据集工厂{ 公共(public)静态数据集 createDataset() { 尝试 { 返回(数据集)新的 InitialContext().lookup("..."); } catch (异常前){ 抛出新的 RuntimeException(ex); } }
@实体公共(public)类 TestEntity 实现 MyEntity { @ID 私有(private)整数 id; 私有(private)字符串名称; //设置和获取
@PrePersist
public void fillId() {
if (getId() == null || getId() == 0) {
Dataset d = DatasetFactory.createDataset();
Integer i = (Integer) d.fetchJPQLFirstResult("SELECT MAX(te.id) FROM TestEntity te");
if (i == null || i < 100) {
setId(100);
} else {
setId(i + 1);
}
}
}
@PostPersist
public void audit() {
Dataset<Auditing> dataset = DatasetFactory.createDataset();
// dataset.getEntityManager().clear();
Auditing auditing = new Auditing();
auditing.setIdEntidade(String.valueOf(this.getId()));
dataset.insert(auditing);
}
@实体公共(public)类 Auditoria 实现 MyEntity { @ID @GeneratedValue(策略= GenerationType.IDENTITY) 私有(private)整数 id; 私有(private)字符串 idEntity; //设置和获取
公共(public)接口(interface) MyEntity 扩展序列化 { 整数 getId();
日志:
信息:嵌入式已在 47.154 毫秒内成功部署。PlainTextActionReporterSUCCESSSDescription: deploy AdminCommandApplication deployed with name embedded.
2012-01-06 02:56:54,826 [main] INFO com.joaosavio.model.db.DatasetBean (DatasetBean.java:30) - 插入:TestEntity{id=null, name=ea5c2af4-0ca7-48a2- a82a-dbf582c570a9}
Hibernate:从 TestEntity testentity0_ 中选择 max(testentity0_.id) 作为 col_0_0_
Hibernate:插入到 TestEntity (name, id) 值 (?, ?)
2012-01-06 02:56:56,344 [main] INFO com.joaosavio.model.db.DatasetBean (DatasetBean.java:30) - 插入:Auditoria{id=null, idEntidade=100}
Hibernate:插入到 TestEntity (name, id) 值 (?, ?)
2012-01-06 02:56:56,350 [main] WARN org.hibernate.engine.jdbc.spi.SqlExceptionHelper (SqlExceptionHelper.java:143) - SQL 错误:2627,SQLState:23000
2012-01-06 02:56:56,352 [main] 错误 org.hibernate.engine.jdbc.spi.SqlExceptionHelper (SqlExceptionHelper.java:144) - 违反 PRIMARY KEY 约束 'PK_TestEntity_76818E95'。无法在对象“dbo.TestEntity”中插入重复键。
06/01/2012 02:56:56 com.sun.ejb.containers.BaseContainer postInvoke
警告:在调用 EJB DatasetBean 方法时发生系统异常 public void com.joaosavio.model.db.DatasetBean.insert(java.lang.Object)javax.ejb.TransactionRolledbackLocalException:从 bean 抛出的异常...
引起:javax.persistence.PersistenceException:org.hibernate.exception.ConstraintViolationException:违反 PRIMARY KEY 约束 'PK_TestEntity_76818E95'。无法在对象“dbo.TestEntity”中插入重复键。...
由以下原因引起:org.hibernate.exception.ConstraintViolationException:违反 PRIMARY KEY 约束 'PK_TestEntity_76818E95'。无法在对象“dbo.TestEntity”中插入重复键。
注意事项:
如果我在插入审计实体之前清除实体管理器(在 TestEntity 的@PostPersist 方法中注释代码),我相信一切正常,我相信 TestEntity 会卡在事务中。
我做错了什么???
最佳答案
我曾经见过一个非常相似的问题......你应该 ---
使用@PostPersist 时要非常小心! hibernate bean 持久化或保存操作与数据库插入不同!
问题可能是您假设在插入数据后调用@PostPersist 方法....但是,情况并非总是如此! PostPersist 方法是回调,但它们不是来自数据库的回调!如您所知 - hibernate 可能没有提交您的事务并完全刷新它。如果您尝试使用 PostPersist 来协调数据库事务之间的障碍,那您就犯了一个错误。
解决方案是在一个正确计划和管理的事务中完成所有插入,并制定出键和级联,以便 hibernate 能够以正确的方式为您组织插入——或者只是对存储的硬编码为您完成工作的程序。
我认为您可能会在此处合并有状态和无状态事务逻辑。
关于java - Hibernate 错误在@PostPersist 方法中保留一个实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8753749/
我有一个带有名为“doAudit”的@PostPersist 方法的监听器来审核创建操作。在调试时我看到此方法被调用并且审核记录是在 JAVA 端创建的。但是当我验证数据库时,我没有看到记录。 pub
我有一个持久化实体对象的方法 persistData() 。我有另一个方法 findData() ,它对同一实体类执行 find() 操作以获取持久的主键值。当我在实体类的@PostPersist中调
我已经阅读了有关生命周期事件的文档,以及关于在生命周期事件期间更改或保留新实体的几个问题。调用EnitityManager::flush()似乎是个问题。 好的,但是 looking carefull
我想在实体上添加新的 Feed 项并持续更新。我写了这个事件监听器(postUpdate 是一样的): public function postPersist(LifecycleEventArgs $
我正在尝试在创建另一个实体的基础上创建一个新实体。示例:我有一段关系 Sale Payment 现在,当我坚持销售时,您必须创建一个初始付款,但我不知 Prop 体该怎么做。 我尝试过: 使用@OR
我在使用手动事务时插入/更新 3 个表。我想在事务提交后立即插入到历史表中。这意味着有 3 em.persist操作(对于每个表),并且只有在提交它们之后我才想调用一个方法。 这是我的代码: @Res
Doctrine 的事件监听类中的 postUpdate 和 postPersist 事件有什么区别?以我的理解,更新和插入都必须坚持下去。那么当可以在 postPersist 事件中处理它时,拥有
我正在尝试设置我的 hibernate 应用程序以在每次创建 Activity 实体时都保留一个新的 Notification 实体 - 目前,我已经尝试了 通知只是无法静默地持续存在(日志中没有错误
假设我有实体 Account: @Entity(name = "ACCOUNT") @EntityListeners(Listener.class) public class AccountEntit
我在数据库中出现双重插入的奇怪错误。我有以下类(class): TestEntity - 具有@PrePersist 和@PostPersist 方法的实体。 Auditoria - 审计实体 Dat
我目前正在使用 @PostPersist 和 @PostUpdate,在这些触发器中我正在持久化其他实体。问题是,这些触发器是否在同一事务中,如果不是,是否可以强制执行? 对我来说,它是这样工作的。当
我正在使用监听器来坚持和根据 Doctrine 进行更新。 唯一的问题是,当调用监听器时,它会创建并更新新的/当前的实体,因此它再次调用自身,从而创建两个实体。 我认为阻止这种情况的唯一方法是拥有一个
在 Symfony 中创建 Doctrine postPersist EventListener 后,我的 IDE 指向 $args->getEntity() 行;由于已被弃用,我不知道如何解决这个问
我有一个 JPA @Entity 类,它使用 @PrePersist 已经有一段时间了。今天我想在需要该实体 ID 的地方添加一些功能。此 ID 由数据库中的 HIBERNATE_SEQUENCE 持
我有一个用于测试 @EntityListeners 功能的小型测试应用程序。当我运行应用程序时,我得到以下堆栈跟踪 Exception in thread "main" org.springframe
我有下一个 ER 图 我想在每次保存 Score 实体时更新 PlayerStat 实体。所以我尝试使用 @PostPersist 注释。当我保存 Score 实体时,调用该注释的函数,但我在此函数中
每当在管理员中完成持久化或更新等操作时,我想创建一个静态 Twig 文件。我在想的是创建一个名为 GenerateStaticListener 的监听器。监听器将监听事件 postPersist 或
我是一名优秀的程序员,十分优秀!