2016-08-03 32 views
1

Ich versuche, Benutzer zu speichern, der die Hibernate-Methode persist verwendet. Nachdem ich meine Testmethode ausgeführt habe, bekomme ich eine Ausnahme. Ich habe viele Themen mit dem gleichen Problem, wie hinzufügen @Transactional der Klasse, geprüft Frühjahr Versionen usw. Aber es hat noch diese AusnahmeHibernate Spring JPA javax.persistence.TransactionRequiredException: Kein transaktionaler EntityManager verfügbar

javax.persistence.TransactionRequiredException: No transactional EntityManager available 

at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:275) 
at com.sun.proxy.$Proxy39.merge(Unknown Source) 
at ua.javagym.repository.jpa.JpaUserRepositoryImpl.save(JpaUserRepositoryImpl.java:28) 
at ua.javagym.service.UserServiceImpl.save(UserServiceImpl.java:23) 
at ua.javagym.service.UserServiceImplTest.testSave(UserServiceImplTest.java:32) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:497) 
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:73) 
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82) 
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:73) 
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:224) 
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83) 
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) 
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68) 
at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163) 
at org.junit.runner.JUnitCore.run(JUnitCore.java:137) 
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69) 
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234) 
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:497) 
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) 

UserServiceImplTest

@ContextConfiguration({ 
    "classpath:spring/spring-app.xml", 
    "classpath:spring/spring-db.xml", 
    "classpath:spring/spring-tools.xml" 
}) 
@RunWith(SpringJUnit4ClassRunner.class) 
public class UserServiceImplTest { 

@Autowired 
protected UserService userService; 

@Test 
public void testSave() throws Exception { 
    User user = new User("Usertest", "userMail", "user", new Date(), Role.USER); 
    userService.save(user); 
} 

UserServiceImpl

@Service 
public class UserServiceImpl implements UserService { 

@Autowired 
private UserRepository repository; 

public User save(User user) { 
    return repository.save(user); 
} 

JpaUserRepositoryImpl

@Repository 
@Transactional 
public class JpaUserRepositoryImpl implements UserRepository { 

@PersistenceContext 
private EntityManager entityManager; 


@Override 
@Transactional 
public User save(User user) { 
    if (!user.isNew()){ 
     entityManager.persist(user); 
    }else entityManager.merge(user); 
    return user; 
} 
} 

Feder app.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" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context-3.0.xsd"> 


<context:annotation-config/> <!--подключаем использование аннотаций--> 
<context:component-scan base-package="ua.javagym.**.service"/> 
<context:component-scan base-package="ua.javagym.**.web"/> 
<context:component-scan base-package="ua.javagym.**.repository.jpa"/> 


</beans> 

Feder db.xml

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:jdbc="http://www.springframework.org/schema/jdbc" 
    xmlns:jee="http://www.springframework.org/schema/jee" 
    xmlns="http://www.springframework.org/schema/beans" xmlns:tx="http://www.springframework.org/schema/cache" 
    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/jdbc 
    http://www.springframework.org/schema/jdbc/spring-jdbc.xsd 
    http://www.springframework.org/schema/jee 

    http://www.springframework.org/schema/jee/spring-jee.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"> 

<context:annotation-config/> 
<tx:annotation-driven /> 

<context:property-placeholder location="classpath:db/mysql/mySQL.properties" system-properties-mode="OVERRIDE"/> 

<jdbc:initialize-database data-source="dataSource"> 
    <jdbc:script location="${jdbc.initLocation}"/> 
    <jdbc:script location="${jdbc.dataLocation}"/> 
</jdbc:initialize-database> 

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/> 
    <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" 
     p:dataSource-ref="dataSource" 
     p:packagesToScan="ua.javagym.model"> 

    <property name="jpaPropertyMap"> 
     <map> 
      <entry key="#{T(org.hibernate.cfg.AvailableSettings).FORMAT_SQL}" value="${hibernate.format_sql}"/> 
      <entry key="#{T(org.hibernate.cfg.AvailableSettings).USE_SQL_COMMENTS}" value="${hibernate.use_sql_comments}"/> 
     </map> 
    </property> 

    <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" 
       p:showSql="${jpa.showSql}"> 
     </bean> 
    </property> 
</bean> 

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" 
     p:entityManagerFactory-ref="entityManagerFactory"/> 

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>gym</groupId> 
<artifactId>gym</artifactId> 
<packaging>war</packaging> 
<version>1.0-SNAPSHOT</version> 
<build> 
    <plugins> 
     <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-compiler-plugin</artifactId> 
      <configuration> 
       <source>1.6</source> 
       <target>1.6</target> 
      </configuration> 
     </plugin> 
    </plugins> 
</build> 

<properties> 
    <logback.version>1.1.2</logback.version> 
    <slf4j.version>1.7.7</slf4j.version> 
    <junit.version>4.12</junit.version> 
    <spring.test>4.1.6.RELEASE</spring.test> 
    <spring.jdbc>4.1.6.RELEASE</spring.jdbc> 
    <spring.version>4.1.6.RELEASE</spring.version> 
    <spring.orm>4.1.6.RELEASE</spring.orm> 
    <spring-data-jpa.version>1.9.0.RELEASE</spring-data-jpa.version> 
    <hibernate.version>5.1.0.Final</hibernate.version> 
    <hibernate.validator>5.1.0.Final</hibernate.validator> 
    <ehcache.version>2.10.1</ehcache.version> 

</properties> 


<dependencies> 
    <!-- http://mvnrepository.com/artifact/ch.qos.logback/logback-classic --> 
    <dependency> 
     <groupId>ch.qos.logback</groupId> <!--реализация API slf4j--> 
     <artifactId>logback-classic</artifactId> 
     <version>${logback.version}</version> 
     <scope>compile</scope> 
    </dependency> 
    <!-- http://mvnrepository.com/artifact/org.slf4j/slf4j-api --> 
    <dependency> 
     <groupId>org.slf4j</groupId> 
     <artifactId>slf4j-api</artifactId> 
     <version>${slf4j.version}</version> 
    </dependency> 
    <!-- http://mvnrepository.com/artifact/org.slf4j/jcl-over-slf4j --> 
    <dependency> 
     <groupId>org.slf4j</groupId> 
     <artifactId>jcl-over-slf4j</artifactId> 
     <version>${slf4j.version}</version> 
    </dependency> 
    <!-- http://mvnrepository.com/artifact/javax.servlet/servlet-api --> 
    <dependency> 
     <groupId>javax.servlet</groupId> 
     <artifactId>servlet-api</artifactId> 
     <version>2.5</version> 
     <scope>provided</scope> 
    </dependency> 
    <dependency> 
     <groupId>javax.servlet</groupId> 
     <artifactId>jstl</artifactId> 
     <version>1.2</version> 
    </dependency> 
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> 
    <dependency> 
     <groupId>org.springframework</groupId> 
     <artifactId>spring-context</artifactId> 
     <version>${spring.version}</version> 
     <exclusions> 
      <exclusion> 
       <groupId>commons-logging</groupId> 
       <artifactId>commons-logging</artifactId> 
      </exclusion> 
     </exclusions> 
    </dependency> 
    <!-- https://mvnrepository.com/artifact/junit/junit --> 
    <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <version>${junit.version}</version> 
    </dependency> 
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-test --> 
    <dependency> 
     <groupId>org.springframework</groupId> 
     <artifactId>spring-test</artifactId> 
     <version>${spring.test}</version> 
    </dependency> 
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --> 
    <dependency> 
     <groupId>org.springframework</groupId> 
     <artifactId>spring-jdbc</artifactId> 
     <version>${spring.jdbc}</version> 
    </dependency> 
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-orm --> 
    <dependency> 
     <groupId>org.springframework</groupId> 
     <artifactId>spring-orm</artifactId> 
     <version>${spring.orm}</version> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework.data</groupId> 
     <artifactId>spring-data-jpa</artifactId> 
     <version>${spring-data-jpa.version}</version> 
    </dependency> 
    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> 
    <dependency> 
     <groupId>mysql</groupId> 
     <artifactId>mysql-connector-java</artifactId> 
     <version>5.1.38</version> 
    </dependency> 
    <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-entitymanager --> 
    <dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-entitymanager</artifactId> 
     <version>${hibernate.version}</version> 
    </dependency> 

    <dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-java8</artifactId> 
     <version>${hibernate.version}</version> 
    </dependency> 
    <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator --> 
    <dependency> 
     <groupId>org.hibernate</groupId> 
     <artifactId>hibernate-validator</artifactId> 
     <version>${hibernate.validator}</version> 
    </dependency> 
    <dependency> 
     <groupId>javax.transaction</groupId> 
     <artifactId>jta</artifactId> 
     <version>1.1</version> 
     <scope>runtime</scope> 
    </dependency> 
    <dependency> 
     <groupId>net.sf.ehcache</groupId> 
     <artifactId>ehcache</artifactId> 
     <version>${ehcache.version}</version> 
    </dependency> 
    <dependency> 
     <groupId>javax.el</groupId> 
     <artifactId>javax.el-api</artifactId> 
     <version>2.2.5</version> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework</groupId> 
     <artifactId>spring-context-support</artifactId> 
     <version>${spring.version}</version> 
     <exclusions> 
      <exclusion> 
       <groupId>commons-logging</groupId> 
       <artifactId>commons-logging</artifactId> 
      </exclusion> 
     </exclusions> 
    </dependency> 
</dependencies> 

User.class

@Entity 
@Table(name = "users") 
@NamedQueries({ 
    @NamedQuery(name = User.DELETE, query = "delete from User u where u.id=:id"), 
    @NamedQuery(name = User.GET_ALL, query = "select u from User u") 
}) 
public class User extends NamedEntity{ 
public static final String DELETE = "User.delete"; 
public static final String GET_ALL = "User.getAlL"; 

@Column(name = "email") 
private String email; 

@Column(name = "password") 
private String password; 

@Column(name = "enabled") 
private boolean enabled = true; 

@Column(name = "registered") 
private Date registered = new Date(); 

@Enumerated(EnumType.ORDINAL) 
@Column(name = "role_id") 
private Role role; 

public User() { 
} 

public User(String name, String email, String password, Date registered, Role role) { 
    super(name); 
    this.email = email; 
    this.password = password; 
    this.enabled = true; 
    this.registered = registered; 
    this.role = role; 
} 

Antwort

2

Haben Sie @EnableTransactionManagement zu Ihrer Konfiguration hinzugefügt?

+1

Ihr Rat war sehr hilfreich! jetzt funktioniert es, danke! –

+0

Ich habe viele Tutorials gesehen und es gab nichts über diese Anmerkung. Ich bin neu in jpa, kannst du mir in ein paar Worten erklären, warum es nicht ohne es geht? –

+0

Hallo, es gibt zwei Konfigurationsansätze beim Einrichten von Federdaten: Annotation-basiert und XML-basiert. – BugProtectionActivist