Nur*_*sha 5 java spring hibernate jpa spring-data-jpa
考虑这个示例,其中我创建了两个 JPA 实体并使用 Spring Data JPA 存储库来执行简单的 CRUD -
import java.sql.Timestamp;
import javax.persistence.Version;
@MappedSuperclass
public class AbstractValueObject {
@Id
@GeneratedValue
private Long id;
@Version
@Column(name = "time_stamp")
private Timestamp version;
public Long getId() {
return id;
}
@Override
public String toString() {
if (id == null) {
return "";
}
return id.toString();
}
}
@Entity
@Table(name = "demo")
public class Demo extends AbstractValueObject {
private String name;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "demo")
private List<Owner> owners;
public Demo() {
owners = new ArrayList<>();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Owner> getOwners() {
return Collections.unmodifiableList(owners);
}
public void addOwner(Owner owner) {
this.owners.add(owner);
owner.setDemo(this);
}
public void addAllOwners(List<Owner> owners) {
this.owners.addAll(owners);
for (Owner owner : owners) {
owner.setDemo(this);
}
}
public void update(Demo demo) {
this.setName(demo.getName());
this.owners.clear();
this.addAllOwners(demo.getOwners());
}
}
@Entity
@Table(name = "owner")
public class Owner extends AbstractValueObject {
private String attribute;
@ManyToOne(cascade = CascadeType.ALL, optional = false)
@JoinColumn(name = "demo_id", nullable = false)
private Demo demo;
public String getAttribute() {
return attribute;
}
public void setAttribute(String attribute) {
this.attribute = attribute;
}
public Demo getDemo() {
return demo;
}
public void setDemo(Demo demo) {
this.demo = demo;
}
}
Run Code Online (Sandbox Code Playgroud)
之后,我为Demo实体创建了一个 JPA 存储库,从JpaRepository-
import org.springframework.data.jpa.repository.JpaRepository;
public interface DemoRepository extends JpaRepository<Demo, Long> {}
Run Code Online (Sandbox Code Playgroud)
对应的服务实现——
import javax.annotation.Resource;
import org.springframework.transaction.annotation.Transactional;
public class DemoServiceImpl implements DemoService {
@Resource
private DemoRepository demoRepository;
@Override
@Transactional
public Demo create(Demo demo) {
return demoRepository.save(demo);
}
@Override
@Transactional
public Demo update(long id, Demo demo) {
Demo dbDemo = demoRepository.findOne(id);
if (dbDemo == null) {
return demo;
}
dbDemo.update(demo);
return dbDemo;
}
@Transactional
public void testRun() {
Owner owner = new Owner();
owner.setAttribute("attribute");
Demo demo = new Demo();
demo.setName("demo");
demo.addOwner(owner);
this.create(demo);
demo.setName("another");
this.update(demo.getId(), demo);
}
}
Run Code Online (Sandbox Code Playgroud)
persistence.xml 文件 -
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="jpa-optimistic-locking" transaction-type="RESOURCE_LOCAL">
</persistence-unit>
</persistence>
Run Code Online (Sandbox Code Playgroud)
Spring app-context.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:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.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-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:component-scan base-package="com.keertimaan.example.jpaoptimisticlocking" />
<jpa:repositories base-package="com.keertimaan.example.jpaoptimisticlocking.repository" />
<bean id="demoService" class="com.keertimaan.example.jpaoptimisticlocking.service.DemoServiceImpl" />
<!-- JPA/Database/Transaction Configuration -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test" />
<property name="user" value="root" />
<property name="password" value="admin123" />
<property name="minPoolSize" value="1" />
<property name="maxPoolSize" value="2" />
<property name="acquireIncrement" value="1" />
<property name="maxStatements" value="5" />
<property name="idleConnectionTestPeriod" value="500" />
<property name="maxIdleTime" value="1000" />
<property name="loginTimeout" value="800" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="jpa-optimistic-locking" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="persistenceProvider">
<bean class="org.hibernate.jpa.HibernatePersistenceProvider" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
Run Code Online (Sandbox Code Playgroud)
现在每当我尝试在 Windows 7 上更新这样的实体时 -
public class App {
public static void main(String[] args) {
DemoService demoService = (DemoService) SpringHelper.INSTANCE.getBean("demoService");
demoService.testRun();
}
}
Run Code Online (Sandbox Code Playgroud)
我得到这样的例外 -
线程“main”中的异常 org.springframework.orm.ObjectOptimisticLockingFailureException:类 [com.keertimaan.example.jpaoptimisticlocking.domain.Demo] 的对象,标识符为 [4]:乐观锁定失败;嵌套异常是 org.hibernate.StaleObjectStateException:行已被另一个事务更新或删除(或未保存的值映射不正确):[com.keertimaan.example.jpaoptimisticlocking.domain.Demo#4] 在 org.springframework.orm.jpa .vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:228) 在 org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:155) 在 org.springframework.orm.jpa.vendor。 :519) 在 org.springframework.transaction.support。
如果我在 Ubuntu 中运行相同的示例,那么我完全没有异常并且我的应用程序成功完成。这是为什么?
我使用的是 Windowsw 7 64 位版本 -
操作系统名称:Microsoft Windows 7 Enterprise
操作系统版本:6.1.7601 Service Pack 1 Build 7601
我的 Ubuntu 版本是 12.04.5 64 位版本。
Windows 中使用的 JDK:jdk7 更新 75
Ubuntu中使用的JDK:jdk7 update 51
Windows 中的 MySQL 服务器版本:5.6.23-log MySQL Community Server (GPL)
Ubuntu 中的 MySQL 服务器版本:5.5.41-0ubuntu0.12.04.1 (Ubuntu)
| 归档时间: |
|
| 查看次数: |
1943 次 |
| 最近记录: |