2016-08-03 121 views
1

我尝试使用hibernate方法保存用户persist。 我运行我的测试方法后,我得到一个异常。我查了同样的问题很多话题,比如添加@Transactional的类,检查春季版本等,但它仍然有此异常Hibernate Spring JPA javax.persistence.TransactionRequiredException:没有事务性的EntityManager可用

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; 
} 
} 

弹簧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> 

弹簧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; 
} 

回答

2

您是否已将@EnableTransactionManagement添加到您的配置中?

+1

你的建议是非常有益的! 现在有用,谢谢! –

+0

我看了很多教程,并没有关于这个注释。我是jpa的新手,你能用几句话来解释我为什么没有它就无法工作? –

+0

嗨,有两种配置方法来设置弹簧数据:基于注释和基于xml。 – BugProtectionActivist

相关问题