2016-07-20 3 views
0

다음 문제를 해결할 수 없습니다. My Spring + JPA + hibernate + Oracle DB 애플리케이션은 데이터베이스에서 데이터를 올바르게 읽지 만 저장하지는 않습니다. 비슷한 주제로 인터넷 검색 (이 포럼)을 발견했지만 불행히도 내 코드에서 수정할 수 없습니다.JPA entityManager가 데이터를 저장하지 않음, flush가 "progres에서 트랜잭션 없음"예외 발생

생각 중 하나는 persist() 메서드를 호출 한 후에 entityManager.flush()을 추가하는 것이지만 예외는 javax.persistence.TransactionRequiredException: no transaction is in progress입니다.

beginnig에서 나는 또한 내 저장소 클래스에 EntityManagerFactory을 사용했지만 다른 주석을 기반으로 EntityManager@PersistenceContext annotation을 사용하도록 마이그레이션했습니다.

도움을 주시면 감사하겠습니다.

의 pom.xml :

<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <groupId>com.example</groupId> 
    <artifactId>hr_db</artifactId> 
    <version>0.0.1-SNAPSHOT</version> 
    <packaging>jar</packaging> 

    <name>oralce_hr_hibernate</name> 
    <description>Oracle HR database</description> 

    <parent> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-parent</artifactId> 
     <version>1.3.6.RELEASE</version> 
     <relativePath/> <!-- lookup parent from repository --> 
    </parent> 

    <properties> 
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
     <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> 
     <java.version>1.8</java.version> 
    </properties> 

    <dependencies> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-web</artifactId> 
     </dependency>   
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-test</artifactId> 
      <scope>test</scope> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-orm</artifactId> 
     </dependency>   

<!-- http://stackoverflow.com/questions/9898499/oracle-jdbc-ojdbc6-jar-as-a-maven-dependency --> 
<!-- mvn install:install-file -DgroupId=com.oracle -DartifactId=ojdbc6 -Dversion=11.2.0.3 -Dpackaging=jar -Dfile=ojdbc6.jar -DgeneratePom=true --> 
     <dependency> 
      <groupId>com.oracle</groupId> 
      <artifactId>ojdbc6</artifactId> 
      <version>11.2.0.4</version> 
     </dependency>  

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

     <dependency> 
      <groupId>org.hibernate</groupId> 
      <artifactId>hibernate-core</artifactId> 
     </dependency> 

    <dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-entitymanager</artifactId> 
    </dependency>   

     <dependency> 
      <groupId>org.springframework.data</groupId> 
      <artifactId>spring-data-commons</artifactId> 
     </dependency> 
    </dependencies> 

    <build> 
     <plugins> 
      <plugin> 
       <groupId>org.springframework.boot</groupId> 
       <artifactId>spring-boot-maven-plugin</artifactId> 
      </plugin> 
     </plugins> 
    </build> 


</project> 

Job.java : 여기

내 코드입니다

package com.example.entities; 

import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.Id; 
import javax.persistence.Table; 

@Entity 
@Table(name = "JOBS") 
public class Job { 
    @Id 
    @Column(name = "JOB_ID") 
    String jobId; 

    @Column(name = "JOB_TITLE") 
    String jobTitle; 

    @Column(name = "min_salary") 
    int minSalary; 

    @Column(name = "max_salary") 
    int maxSalary; 

    public Job() { 
    } 

    public Job(String id) { 
     jobId = id; 
    } 

    public String getJobId() { 
     return jobId; 
    } 

    public void setJobId(String jobId) { 
     this.jobId = jobId; 
    } 

    public String getJobTitle() { 
     return jobTitle; 
    } 

    public void setJobTitle(String jobTitle) { 
     this.jobTitle = jobTitle; 
    } 

    public int getMinSalary() { 
     return minSalary; 
    } 

    public void setMinSalary(int minSalary) { 
     this.minSalary = minSalary; 
    } 

    public int getMaxSalary() { 
     return maxSalary; 
    } 

    public void setMaxSalary(int maxSalary) { 
     this.maxSalary = maxSalary; 
    } 

} 

JobRepository.java :

package com.example.repositories.interfaces; 

import org.springframework.data.repository.Repository; 

import com.example.entities.Job; 

public interface JobRepository extends Repository<Job, String> { 
    public Job findByJobId(String id); 

    public void saveOrUpdate(Job job); 

    public void delete(Job job); 

    public void deleteByJobId(String jobId); 

    public void persistJob(Job job); 
} 

JobRepositoryImpl.java :

package com.example.repositories; 

import javax.persistence.EntityManager; 
import javax.persistence.PersistenceContext; 

import org.springframework.transaction.annotation.Propagation; 
import org.springframework.transaction.annotation.Transactional; 

import com.example.entities.Job; 
import com.example.repositories.interfaces.JobRepository; 

@Transactional(propagation = Propagation.REQUIRED) 
public class JobRepositoryImpl implements JobRepository { 

    @PersistenceContext 
    private EntityManager entityManager; 

    public JobRepositoryImpl() { 
    } 

    public EntityManager getEntityManager() { 
     return entityManager; 
    } 

    public void setEntityManager(EntityManager entityManager) { 
     this.entityManager = entityManager; 
    } 

    @Override 
    public Job findByJobId(String id) { 
     return (Job) entityManager.find(Job.class, id); 
    } 

    @Override 
    public void saveOrUpdate(Job job) { 
     entityManager.merge(job); 
    } 

    @Override 
    public void delete(Job job) { 
     entityManager.remove(job); 
    } 

    @Override 
    public void deleteByJobId(String jobId) { 
     entityManager.remove(findByJobId(jobId)); 
    } 

    @Override 
    public void persistJob(Job job) { 
     entityManager.persist(job); 
     // this is causing javax.persistence.TransactionRequiredException: no transaction is in progress 
     // entityManager.flush(); 
    } 
} 

응용 프로그램-config.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:context="http://www.springframework.org/schema/context" 
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd 
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 

    <context:property-placeholder 
     location="file:///${app.properties.dir}/db.properties" /> 

    <bean 
     class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /> 

    <tx:annotation-driven /> 

    <bean id="transactionManager" 
     class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
     <property name="sessionFactory" ref="sessionFactory" /> 
    </bean> 

    <bean id="sessionFactory" 
     class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
     <property name="dataSource" ref="dataSource" /> 
     <property name="packagesToScan" value="com.example.entities" /> 
    </bean> 

    <bean id="entityManagerFactory" 
     class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
     <property name="dataSource" ref="dataSource" /> 
     <property name="packagesToScan"> 
      <list> 
       <value>com.example.entities</value> 
      </list> 
     </property> 
     <property name="jpaVendorAdapter" ref="jpaVendorAdapter" /> 
     <property name="persistenceUnitName" value="HR" /> 
    </bean> 

    <bean id="jpaVendorAdapter" 
     class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
     <property name="database" value="ORACLE" /> 
     <property name="showSql" value="true" /> 
     <property name="generateDdl" value="false" /> 
     <property name="databasePlatform" value="org.hibernate.dialect.OracleDialect" /> 
    </bean> 

    <bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource" 
     destroy-method="close"> 
     <property name="URL" value="${test.oracle.url}" /> 
     <property name="user" value="${test.oracle.username}" /> 
     <property name="password" value="${test.oracle.password}" /> 
     <property name="connectionCachingEnabled" value="true" /> 
    </bean> 

</beans> 

저장소 - IMPL-config.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:aop="http://www.springframework.org/schema/aop" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd 
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 

    <bean id="jobRepository" class="com.example.repositories.JobRepositoryImpl"> 
    </bean> 

</beans> 

JobRepositoryTest.java : 콘솔에서

package com.example.repositories; 

import static org.junit.Assert.assertEquals; 

import java.util.logging.Logger; 

import org.junit.Before; 
import org.junit.Test; 
import org.springframework.context.ConfigurableApplicationContext; 
import org.springframework.context.support.ClassPathXmlApplicationContext; 
import org.springframework.test.annotation.Rollback; 
import org.springframework.transaction.annotation.Propagation; 
import org.springframework.transaction.annotation.Transactional; 

import com.example.entities.Job; 
import com.example.repositories.interfaces.JobRepository; 

@Transactional(propagation = Propagation.REQUIRED) 
public class JobRepositoryTest { 

    private static final String TEST_JOB_ID = "TEST_JOB"; 

    JobRepository repository; 

    ConfigurableApplicationContext context; 

    Logger logger = Logger.getLogger(JobRepositoryTest.class.getName()); 

    @Before 
    public void setUp() { 
     // Create the test configuration for the application from two files 
     context = new ClassPathXmlApplicationContext("classpath:/com/example/application-config.xml", 
       "classpath:/com/example/repositories/repositories-impl-config.xml"); 
     // Get the bean to use to invoke the application 
     repository = context.getBean(JobRepository.class); 
    } 

    // Test is passing 
    @Test 
    public void testFindById() { 
     Job job = repository.findByJobId("AD_PRES"); 
     assertEquals("President", job.getJobTitle()); 
     assertEquals(20080, job.getMinSalary()); 
     assertEquals(40000, job.getMaxSalary()); 
    } 

    // Doesn't save the job 
    @Test 
    @Rollback(false) 
    public void testSaveOrUpdateJob() { 
     Job job = createTestJob(); 

     logger.info("BEFORE"); 
     repository.persistJob(job); 
     logger.info("AFTER"); 
    } 


    private Job createTestJob() { 
     Job testJob = new Job(TEST_JOB_ID); 
     testJob.setJobTitle("Test job title"); 
     testJob.setMinSalary(0); 
     testJob.setMaxSalary(9999); 
     return testJob; 
    } 
} 

출력 :

INFO: BEFORE 
23:13:04.579 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.transaction.interceptor.TransactionInterceptor#0' 
23:13:04.581 [main] DEBUG org.springframework.transaction.annotation.AnnotationTransactionAttributeSource - Adding transactional method 'JobRepositoryImpl.persistJob' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '' 
23:13:04.586 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'transactionManager' 
23:13:04.591 [main] DEBUG org.springframework.orm.hibernate4.HibernateTransactionManager - Creating new transaction with name [com.example.repositories.JobRepositoryImpl.persistJob]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '' 
23:13:04.652 [main] DEBUG org.springframework.orm.hibernate4.HibernateTransactionManager - Opened new Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[[email protected] [email protected] [email protected] [email protected] [email protected]267b [email protected]6f1 [email protected]7 [email protected]4e08 unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] for Hibernate transaction 
23:13:04.653 [main] DEBUG org.springframework.orm.hibernate4.HibernateTransactionManager - Preparing JDBC Connection of Hibernate Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[[email protected] [email protected] [email protected] [email protected] [email protected]267b [email protected]6f1 [email protected]7 [email protected]4e08 unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] 
23:13:04.653 [main] DEBUG org.hibernate.engine.jdbc.internal.LogicalConnectionImpl - Obtaining JDBC connection 
23:13:04.653 [main] DEBUG org.hibernate.engine.jdbc.internal.LogicalConnectionImpl - Obtained JDBC connection 
23:13:04.654 [main] DEBUG org.hibernate.engine.transaction.spi.AbstractTransactionImpl - begin 
23:13:04.655 [main] DEBUG org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction - initial autocommit status: true 
23:13:04.655 [main] DEBUG org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction - disabling autocommit 
23:13:04.656 [main] DEBUG org.springframework.orm.hibernate4.HibernateTransactionManager - Exposing Hibernate transaction as JDBC transaction [[email protected]] 
23:13:04.658 [main] DEBUG org.springframework.orm.jpa.EntityManagerFactoryUtils - Opening JPA EntityManager 
23:13:04.686 [main] DEBUG org.springframework.orm.jpa.EntityManagerFactoryUtils - Registering transaction synchronization for JPA EntityManager 
23:13:04.697 [main] DEBUG org.hibernate.event.internal.AbstractSaveEventListener - Generated identifier: TEST_JOB, using strategy: org.hibernate.id.Assigned 
23:13:04.730 [main] DEBUG org.springframework.orm.jpa.EntityManagerFactoryUtils - Closing JPA EntityManager 
23:13:04.732 [main] DEBUG org.springframework.orm.hibernate4.HibernateTransactionManager - Initiating transaction commit 
23:13:04.732 [main] DEBUG org.springframework.orm.hibernate4.HibernateTransactionManager - Committing Hibernate transaction on Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[[email protected] [email protected] [email protected] [email protected] [email protected]267b [email protected]6f1 [email protected]7 [email protected]4e08 unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] 
23:13:04.732 [main] DEBUG org.hibernate.engine.transaction.spi.AbstractTransactionImpl - committing 
23:13:04.734 [main] DEBUG org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction - committed JDBC Connection 
23:13:04.734 [main] DEBUG org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction - re-enabling autocommit 
23:13:04.735 [main] DEBUG org.springframework.orm.hibernate4.HibernateTransactionManager - Closing Hibernate Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[[email protected] [email protected] [email protected] [email protected] [email protected]267b [email protected]6f1 [email protected]7 [email protected]4e08 unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] after transaction 
23:13:04.735 [main] DEBUG org.hibernate.engine.jdbc.internal.LogicalConnectionImpl - Releasing JDBC connection 
23:13:04.735 [main] DEBUG org.hibernate.engine.jdbc.internal.LogicalConnectionImpl - Released JDBC connection 
Jul 20, 2016 11:13:04 PM com.example.repositories.JobRepositoryTest testSaveOrUpdateJob 
INFO: AFTER 
+0

마지막으로이 질문의 답을 http://stackoverflow.com/questions/5372859/no-transaction-starts-within-spring-transactional-method가 내 문제를 해결했습니다. – kpater87

답변

0

동일한 예외가 발생했습니다. 내 간단한 해결책은 플러시 메서드를 호출하지 않는 것이 었습니다. 그런 다음 sqlserver 데이터베이스에 저장할 수 있습니다. 이상적인 해결책이 아닙니다. 추가 정보는 철저히 조사한 후에 제공됩니다

+0

이 질문을 확인하십시오 : http://stackoverflow.com/questions/5372859/no-transaction-starts-within-spring-transactional-method. 거기에 내 문제에 대한 해결책을 찾았습니다. – kpater87

관련 문제