我试图让Spring Data JPA项目工作。我的数据不会保留在employeeManager.addEmployee(employee)
上(见下文)。
实体:
package com.howtodoinjava.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.springframework.data.neo4j.annotation.Indexed;
@Entity
@Table(name = "EMPLOYEE")
@SuppressWarnings("SerializableClass")
public class EmployeeEntity {
@Id
@Column(name = "ID")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@Column(name = "FIRSTNAME")
private String firstname;
@Column(name = "LASTNAME")
private String lastname;
@Indexed
@Column(name = "EMAIL")
private String email;
@Column(name = "TELEPHONE")
private String telephone;
public String getEmail() {
return email;
}
public String getTelephone() {
return telephone;
}
public void setEmail(String email) {
this.email = email;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
public String getFirstname() {
return firstname;
}
public String getLastname() {
return lastname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
服务:
package com.howtodoinjava.service;
import com.howtodoinjava.entity.EmployeeEntity;
import com.howtodoinjava.repository.jpa.EmployeeJpaRepository;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.neo4j.helpers.collection.IteratorUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional
public class EmployeeManagerJpa implements EmployeeManager {
@Autowired
private EmployeeJpaRepository employeeRepository;
@Transactional
public void addEmployee(EmployeeEntity employee) {
employeeRepository.save(employee);
}
@Transactional
public List<EmployeeEntity> getAllEmployees() {
return (List<EmployeeEntity>) makeCollection(employeeRepository.findAll());
}
@Transactional
public void deleteEmployee(Long employeeId) {
employeeRepository.delete(getEmployee(employeeId));
}
@Transactional
public EmployeeEntity getEmployee(Long employeeId) {
return employeeRepository.findOne(employeeId);
}
public static <E> Collection<E> makeCollection(Iterable<E> iter) {
Collection<E> list = new ArrayList<E>();
for (E item : iter) {
list.add(item);
}
return list;
}
}
存储库:
package com.howtodoinjava.repository.jpa;
import com.howtodoinjava.entity.EmployeeEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.CrudRepository;
public interface EmployeeJpaRepository extends JpaRepository<EmployeeEntity, Long> {}
应用程序上下文分为两个文件(在web.xml的context-param中读取为employee-servlet-*.xml
):
employee-servlet-app.xml:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
xmlns:tx="http://www.springframework.org/schema/tx"
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/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/data/neo4j
http://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<context:spring-configured/>
<context:component-scan base-package="com.howtodoinjava">
<context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>
<tx:annotation-driven mode="proxy" transaction-manager="transactionManager" />
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
employee-servlet-jpa.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
xmlns:tx="http://www.springframework.org/schema/tx"
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/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<jpa:repositories base-package="com.howtodoinjava.repository.jpa" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" >
<property name="packagesToScan" value="com.howtodoinjava.entity" />
<property name="persistenceUnitName" value="SpringDataJPA" />
<!--property name="dataSource" ref="dataSource" /-->
<property name="jpaProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="persistenceProvider">
<bean class="org.hibernate.jpa.HibernatePersistenceProvider" />
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
</beans>
最后,persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="SpringDataJPA" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/atom" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="123456" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
</persistence>
我在控制台上看到了这个:
Aug 27, 2014 3:06:48 AM org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation
INFO: HHH000204: Processing PersistenceUnitInfo [
name: SpringDataJPA
...]
Aug 27, 2014 3:06:48 AM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.3.6.Final}
Aug 27, 2014 3:06:48 AM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
Aug 27, 2014 3:06:48 AM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
Aug 27, 2014 3:06:48 AM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
Aug 27, 2014 3:06:48 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH000402: Using Hibernate built-in connection pool (not for production use!)
Aug 27, 2014 3:06:48 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/atom]
Aug 27, 2014 3:06:48 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000046: Connection properties: {user=root, password=****}
Aug 27, 2014 3:06:48 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000006: Autocommit mode: false
Aug 27, 2014 3:06:48 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
Aug 27, 2014 3:06:48 AM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
Aug 27, 2014 3:06:48 AM org.hibernate.engine.jdbc.internal.LobCreatorBuilder useContextualLobCreation
INFO: HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4
Aug 27, 2014 3:06:49 AM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
Aug 27, 2014 3:06:49 AM org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: HHH000228: Running hbm2ddl schema update
Aug 27, 2014 3:06:49 AM org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: HHH000102: Fetching database metadata
Aug 27, 2014 3:06:49 AM org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: HHH000396: Updating schema
Aug 27, 2014 3:06:49 AM org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: HHH000261: Table found: atom.employee
Aug 27, 2014 3:06:49 AM org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: HHH000037: Columns: [firstname, telephone, id, email, lastname]
Aug 27, 2014 3:06:49 AM org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: HHH000108: Foreign keys: []
Aug 27, 2014 3:06:49 AM org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: HHH000126: Indexes: [primary]
Aug 27, 2014 3:06:49 AM org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: HHH000232: Schema update complete
Hibernate: select employeeen0_.ID as ID1_0_, employeeen0_.EMAIL as EMAIL2_0_, employeeen0_.FIRSTNAME as FIRSTNAM3_0_, employeeen0_.LASTNAME as LASTNAME4_0_, employeeen0_.TELEPHONE as TELEPHON5_0_ from EMPLOYEE employeeen0_
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 4.519 sec
表格是正确创建的,只是save()方法没有保存我的数据。我创建了一个小的JUnit测试,我在调用后检查:employeeManager.addEmployee(employee);
如果记录数量增加了。
/ * *要更改此许可证标题,请在“项目属性”中选择“许可证标题”。 *要更改此模板文件,请选择“工具”|模板 *并在编辑器中打开模板。 * /
package com.howtodoinjava;
import com.howtodoinjava.entity.EmployeeEntity;
import com.howtodoinjava.service.EmployeeManager;
import junit.framework.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath*:employee-servlet*.xml")
@Transactional
public class EmployeeManagerTest {
@Test
public void emptyTest() {
}
@Autowired
@Qualifier("employeeManagerJpa")
EmployeeManager employeeManager;
@Test
public void test() {
EmployeeEntity employee = new EmployeeEntity();
employee.setFirstname("Tom");
employee.setLastname("One");
employee.setTelephone("12-154-789");
employee.setEmail("tom_one@mail.com");
EmployeeEntity employee1 = new EmployeeEntity();
employee1.setFirstname("Kat");
employee1.setLastname("Two");
employee1.setTelephone("12-154-789");
employee1.setEmail("kat_two@mail.com");
employeeManager.addEmployee(employee);
employeeManager.addEmployee(employee1);
Assert.assertEquals("Two",employee1.getLastname()); // True
Assert.assertEquals(0, employeeManager.getAllEmployees().size()); // Always true
}
}
编辑:如果我使用saveAndFlush()强制写入,则会收到无事务错误: org.springframework.dao.InvalidDataAccessApiUsageException:没有正在进行的事务;嵌套异常是javax.persistence.TransactionRequiredException:没有正在进行的事务
我检查了网络上发现的大多数修补程序(包括<x:annotation-driven />
参数,@Transactional
参数,删除了@Service
注释并在employee-servlet-app.xml
上下文文件中明确创建了bean) 。
非常感谢任何其他建议。 随意询问任何其他可能有用的信息。
答案 0 :(得分:0)
在你的persistence.xml
中
<persistence-unit name="SpringDataJPA" transaction-type="RESOURCE_LOCAL">
交易类型不应该是JTA
吗?
默认行为afaik是一个事务总是自动创建,无论如何,但它是只读的。因此,如果您的配置(或代码)出现问题,则不会保留任何内容。