【问题标题】:Spring Data JPA with Hibernate - OnetoMany Relationship Mapped Entities - Partial Commit IssueSpring Data JPA with Hibernate - 一对多关系映射实体 - 部分提交问题
【发布时间】:2016-01-17 04:13:29
【问题描述】:

我在两个实体类之间有一对多的关系。如果在插入子项期间发生错误,则会发生父项的部分插入,但子记录保持未持久化。这里配置的 EntityManager 应该处理事务的回滚,但事实并非如此。

这是我的实体类:

@Entity
@Table(name="parent")
public class Parent implements Serializable { 

   @Id
    @SequenceGenerator(name = "seq_parent", sequenceName = "seq_parent")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_parent")
    @Column(name="PARENT_ID")
    private Long id;

    @OneToMany(cascade = CascadeType.ALL, mappedBy="parent")
    private Set<Child> childDetails;

}


@Entity
@Table(name="child")
public class Child implements Serializable {

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="PARENT_ID")
    private Parent parent;

}

Now my Service Class Method :

public class ServiceImpl implements Service {

 @PersistanceContext
 private EntityManager entityManger;

 @Transactional
 public void persist() {
    Parent parent = new Parent();
    Set<Child> childSet = new HashSet<>();
    Child child = new Child();
    child.setParent(parent);
    childSet.add(child );
    parent.add(childSet);
    entityManager.persist(parent);        
 }
}

Here are my JavaConfig in Spring for transactionManager and DataSource :



@Configuration
@ImportResource({ "classpath:META-INF/spring/audit/auditing-dbsink-config.xml",
        "classpath:META-INF/spring/services-context.xml" })
@EnableTransactionManagement(order = 20)
public class DatabaseConfiguration implements EnvironmentAware {

}

app-datasource.xml :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
       xmlns:jee="http://www.springframework.org/schema/jee" xmlns:util="http://www.springframework.org/schema/util"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
            http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.1.xsd
            http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">


<tx:jta-transaction-manager/>
    <context:annotation-config/>

    <jee:jndi-lookup id="datasource" jndi-name="java:jboss/datasources/jdbc/datasource" lookup-on-startup="true"
                     proxy-interface="javax.sql.DataSource"/>

   <bean id="entityManagerFactory"
          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
          parent="abstractEntityManagerFactory" lazy-init="true">
        <property name="dataSource" ref="dataSource"/>
        <property name="persistenceUnitName" value="oracle_pu"/>
    </bean>

</beans>

现在的问题是 TransactionManager 不会回滚完整的事务,以防在持久化子记录时发生异常。

请稍微说明一下,因为我真的无法继续前进。

【问题讨论】:

  • 你在任何地方处理抛出的异常吗?
  • @DraganBozanovic 是的,我正在处理异常以将其转换为业务异常并登录到异常监控区域。这会影响事务处理吗?
  • 是的,确实如此。请看下面我的回答。
  • @DraganBozanovic 在任何情况下,交易要么保存孩子和父母,要么都不保存。但按照 Nik,他只能(部分)保存父级。Nik,你能发布 Parent & Child 实体的完整代码吗?
  • @MadhusudanaReddySunnapu 完整代码块与我的问题中发布的相同。我只是创建父实体和子实体来初始化它们所需的属性,然后调用实体管理器持久方法。知道为什么会发生部分提交。有什么线索吗?

标签: java spring hibernate jpa spring-transactions


【解决方案1】:

默认情况下,Spring 在抛出检查异常时不会回滚事务。来自documentation

在其默认配置中,Spring 框架的事务 基础设施代码在 运行时的情况,未经检查的异常;也就是说,当抛出 exception 是 RuntimeException 的一个实例或子类。 ( 错误 还将 - 默认情况下 - 导致回滚)。已检查的异常 从事务方法抛出的 not 会导致 在默认配置中回滚。

有关如何更改此行为的更多详细信息,请参阅链接文档。例如,我发现最直观的方法是针对所有异常回滚事务:

<tx:advice id="txAdvice">
    <tx:attributes>
        <tx:method name="*" rollback-for="Throwable" />
    </tx:attributes>
</tx:advice>

【讨论】:

  • @Dragon - 我尝试通过放置
  • @Nik 你是否从事务上下文中抛出检查异常?
  • @Dragon 我正在处理启动此持久调用的服务中的异常。发起持久调用的服务是非事务性的。
猜你喜欢
  • 2020-11-30
  • 2021-05-22
  • 1970-01-01
  • 2021-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-22
  • 1970-01-01
相关资源
最近更新 更多