簡體   English   中英

在MERGE JPA之后更新ROLLEDBACK

[英]Update ROLLEDBACK after em.MERGE JPA

大家好 當我嘗試合並我的實體時遇到問題。 我通過放置請求從其余服務中使用新字段“名稱”解析對象實體。 我嘗試將具有新“名稱”字段的實體合並到我的數據庫中,但是更新操作后出現了回滾,也許您知道為什么嗎? 這是我的控制器

@RequestMapping(value = "/updDep", method = RequestMethod.PUT)
      @ResponseBody
      public String updDeps(@RequestBody Department department ) {
        departmentService.addDepartment(department);
        System.out.println("after merge;  in controller");
        return "Success";
    }

和部門服務類使用addDepartment()方法:

@Repository
public class DepartmentServiceImpl implements  DepartmentService {

    @PersistenceContext(unitName = "MyPersistenceUnit")
    private EntityManager entityManager;
....
//getter/setter entityManager....
...
@Override
@Transactional
public void updDepartment(Department department) {
    Department department1 = findById(department.getId());
    department1.setName(department.getName());
    /*  NOT WORKS TOO, STILL ROOLBAKED!
    Department managedDep =  getEntityManager().merge(department);   
    managedDep.setName(department.getName());
    */
}

項目結構: 在此處輸入圖片說明

persistence.xml中

 <persistence-unit name="MyPersistenceUnit" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <properties>
            <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/testbd"/>
            <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
            <property name="hibernate.connection.username" value="root"/>
            <property name="hibernate.connection.password" value="root"/>
            <!--<property name="hibernate.hbm2ddl.import_files" value= "import.sql"/>-->
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.format_sql" value="true"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
        </properties>
    </persistence-unit>

</persistence>

彈簧配置

 <mvc:annotation-driven />

    <context:annotation-config />
    <context:component-scan base-package="epam.rest" />

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix">
            <value>/WEB-INF/pages/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location">
            <value>classpath:jdbc.properties</value>
        </property>
    </bean>

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />

    </bean>

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
         <property name="persistenceUnitName" value="MyPersistenceUnit"/>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="dataSource" ref="dataSource" />
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>
    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
</beans>

LOG4J日志:

11:55:42,672 TRACE DefaultFlushEntityEventListener:281 - Updating entity: [epam.rest.entity.Department#1]
11:55:42,681 DEBUG Collections:190 - Collection found: [epam.rest.entity.Department.worker#1], was: [epam.rest.entity.Department.worker#1] (initialized)
11:55:42,682 TRACE AbstractFlushingEventListener:242 - Processing unreferenced collections
11:55:42,682 TRACE AbstractFlushingEventListener:254 - Scheduling collection removes/(re)creates/updates
11:55:42,682 DEBUG AbstractFlushingEventListener:118 - Flushed: 0 insertions, 1 updates, 0 deletions to 4 objects
11:55:42,683 DEBUG AbstractFlushingEventListener:125 - Flushed: 0 (re)creations, 0 updates, 0 removals to 1 collections
11:55:42,683 DEBUG EntityPrinter:114 - Listing entities:
11:55:42,684 DEBUG EntityPrinter:121 - epam.rest.entity.Worker{id=2, department=epam.rest.entity.Department#1, salary=1200, fio=Kozlovich Andrei Vicktorovich}
11:55:42,684 DEBUG EntityPrinter:121 - epam.rest.entity.Worker{id=1, department=epam.rest.entity.Department#1, salary=1000, fio=Gabriel Alexei Nicolaevich}
11:55:42,684 DEBUG EntityPrinter:121 - epam.rest.entity.Worker{id=3, department=epam.rest.entity.Department#1, salary=1500, fio=Baym Alena Nicolaevna}
11:55:42,686 DEBUG EntityPrinter:121 - epam.rest.entity.Department{id=1, name=IT123, worker=[epam.rest.entity.Worker#2, epam.rest.entity.Worker#3, epam.rest.entity.Worker#1]}
11:55:42,687 TRACE AbstractFlushingEventListener:327 - Executing flush
11:55:42,697 TRACE AbstractEntityPersister:3166 - Updating entity: [epam.rest.entity.Department#1]
11:55:42,698 TRACE AbstractServiceRegistryImpl:146 - Initializing service [role=org.hibernate.engine.jdbc.batch.spi.BatchBuilder]
11:55:42,704 TRACE AbstractServiceRegistryImpl:146 - Initializing service [role=org.hibernate.service.jmx.spi.JmxService]
11:55:42,706 TRACE BatchBuilderImpl:68 - Building batch [size=1]
11:55:42,708 DEBUG SQL:104 - 
    update
        departments 
    set
        name=? 
    where
        id=?
11:55:42,710 TRACE JdbcCoordinatorImpl:319 - Registering statement [com.mysql.jdbc.JDBC4PreparedStatement@646b0e6a: update departments set name=** NOT SPECIFIED ** where id=** NOT SPECIFIED **]
11:55:42,710 TRACE AbstractEntityPersister:2780 - Dehydrating entity: [epam.rest.entity.Department#1]
11:55:42,712 TRACE BasicBinder:84 - binding parameter [1] as [VARCHAR] - IT123
11:55:42,713 TRACE BasicBinder:84 - binding parameter [2] as [BIGINT] - 1
11:55:42,714 TRACE JdbcCoordinatorImpl:358 - Releasing statement [com.mysql.jdbc.JDBC4PreparedStatement@646b0e6a: update departments set name='IT123' where id=1]
11:55:42,715 TRACE JdbcCoordinatorImpl:476 - Closing prepared statement [com.mysql.jdbc.JDBC4PreparedStatement@646b0e6a: update departments set name='IT123' where id=1]
11:55:42,715 TRACE JdbcCoordinatorImpl:249 - Starting after statement execution processing [ON_CLOSE]
11:55:42,717 TRACE JdbcCoordinatorImpl:249 - Starting after statement execution processing [ON_CLOSE]
11:55:42,718 DEBUG AbstractTransactionImpl:203 - rolling back
11:55:42,786 DEBUG JdbcTransaction:164 - rolled JDBC Connection
11:55:42,787 DEBUG JdbcTransaction:126 - re-enabling autocommit
11:55:42,788 TRACE TransactionCoordinatorImpl:136 - after transaction completion
11:55:42,792 TRACE SessionImpl:624 - after transaction completion
11:55:42,794 TRACE SessionImpl:342 - Closing session
11:55:42,795 TRACE JdbcCoordinatorImpl:171 - Closing JDBC container [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl@6583023d]
11:55:42,796 DEBUG JdbcCoordinatorImpl:173 - HHH000420: Closing un-released batch
11:55:42,797 TRACE LogicalConnectionImpl:164 - Closing logical connection
11:55:42,797 DEBUG LogicalConnectionImpl:232 - Releasing JDBC connection
11:55:42,798 TRACE DriverManagerConnectionProviderImpl:233 - Returning connection to pool, pool size: 1
11:55:42,799 DEBUG LogicalConnectionImpl:250 - Released JDBC connection
11:55:42,799 TRACE LogicalConnectionImpl:176 - Logical connection closed

工作人員實體

@Entity
@Table(name = "workers")
public class Worker {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String fio;

    @ManyToOne(cascade =  {CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.EAGER)
    private Department department;

    @Column(nullable = false)
    private Integer salary;
......

部門實體

@Entity
@Table(name ="departments")
public class Department implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String name;

    @OneToMany(cascade =  {CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.EAGER, mappedBy = "department")
    private Set<Worker> worker;
.......

告訴我我錯了什么?

更新1我更新了我的代碼1)刪除persistence.xml 2)刪除服務中的(unitName =“ MyPersistenceUnit”):

 @PersistenceContext
 private EntityManager entityManager;

2)edit despatcher-servlet.xml:現在看起來像這樣:

<mvc:annotation-driven />
    <context:component-scan base-package="epam.rest" />

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix">
            <value>/WEB-INF/pages/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location">
            <value>classpath:jdbc.properties</value>
        </property>
    </bean>

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />

    </bean>


    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan" value="epam.rest.entity" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
        </property>
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.hbm2ddl.auto">create-drop</prop>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>

            </props>
        </property>
    </bean>


    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />

    </bean>

    <bean id="persistenceExceptionTranslationPostProcessor"
    class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
</beans>

但是當我嘗試更新時,我仍然得到相同的ROLLEDBACK

04:14:06,765 TRACE AbstractEntityPersister:3166 - Updating entity: [epam.rest.entity.Department#1]
04:14:06,766 TRACE AbstractServiceRegistryImpl:146 - Initializing service [role=org.hibernate.engine.jdbc.batch.spi.BatchBuilder]
04:14:06,772 TRACE AbstractServiceRegistryImpl:146 - Initializing service [role=org.hibernate.service.jmx.spi.JmxService]
04:14:06,774 TRACE BatchBuilderImpl:68 - Building batch [size=1]
04:14:06,776 DEBUG SQL:104 - update departments set name=? where id=?
04:14:06,777 TRACE JdbcCoordinatorImpl:319 - Registering statement [com.mysql.jdbc.JDBC4PreparedStatement@3918a7aa: update departments set name=** NOT SPECIFIED ** where id=** NOT SPECIFIED **]
04:14:06,778 TRACE AbstractEntityPersister:2780 - Dehydrating entity: [epam.rest.entity.Department#1]
04:14:06,779 TRACE BasicBinder:84 - binding parameter [1] as [VARCHAR] - IT21
04:14:06,780 TRACE BasicBinder:84 - binding parameter [2] as [BIGINT] - 1
04:14:06,782 TRACE JdbcCoordinatorImpl:358 - Releasing statement [com.mysql.jdbc.JDBC4PreparedStatement@3918a7aa: update departments set name='IT21' where id=1]
04:14:06,783 TRACE JdbcCoordinatorImpl:476 - Closing prepared statement [com.mysql.jdbc.JDBC4PreparedStatement@3918a7aa: update departments set name='IT21' where id=1]
04:14:06,783 TRACE JdbcCoordinatorImpl:249 - Starting after statement execution processing [ON_CLOSE]
04:14:06,785 TRACE JdbcCoordinatorImpl:249 - Starting after statement execution processing [ON_CLOSE]
04:14:06,785 DEBUG AbstractTransactionImpl:203 - rolling back
04:14:06,856 DEBUG JdbcTransaction:164 - rolled JDBC Connection
04:14:06,857 DEBUG JdbcTransaction:126 - re-enabling autocommit
04:14:06,858 TRACE TransactionCoordinatorImpl:136 - after transaction completion
04:14:06,862 TRACE SessionImpl:624 - after transaction completion
04:14:06,866 TRACE SessionImpl:342 - Closing session
04:14:06,867 TRACE JdbcCoordinatorImpl:171 - Closing JDBC container [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl@71799400]
04:14:06,867 DEBUG JdbcCoordinatorImpl:173 - HHH000420: Closing un-released batch
04:14:06,868 TRACE LogicalConnectionImpl:164 - Closing logical connection
04:14:06,868 DEBUG LogicalConnectionImpl:232 - Releasing JDBC connection
04:14:06,868 DEBUG LogicalConnectionImpl:250 - Released JDBC connection
04:14:06,869 TRACE LogicalConnectionImpl:176 - Logical connection closed

現在怎么了?! UPDATE2我查看了pom.xml文件:

....
   <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.1.8.Final</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.1.8.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.0-api</artifactId>
            <version>1.0.1.Final</version>
        </dependency>
.....

所以當我刪除ths時:

 <dependency>
                <groupId>org.hibernate.javax.persistence</groupId>
                <artifactId>hibernate-jpa-2.0-api</artifactId>
                <version>1.0.1.Final</version>
            </dependency>

所有的作品!

問題是您向Hibernate提供了兩個不同的jdbc連接信息:

  1. 通過Spring配置的DataSourcw
  2. 通過Hibernate jdbc連接屬性

因為您需要將Spring事務划分集成到Hibernate事務邏輯中,所以只能依賴提供給JPA TransactionManager的數據源。

這就是為什么您還會看到自動提交重新啟用日志的原因。

因此,刪除所有hibernate.connection。*行,您應該可以:

<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/testbd"/>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.username" value="root"/>
<property name="hibernate.connection.password" value="root"/>

刪除這些行后,Hibernate將不會使用其自己的內部JDBC連接提供程序覆蓋DataSource。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM