![](/img/trans.png)
[英]org.hibernate.PersistentObjectException: detached entity passed to persist on new Object
[英]org.hibernate.PersistentObjectException: detached entity passed to persist domain object
我對Spring還是很@ManyToMany
並且一直在使用本教程來幫助我建立@ManyToMany
關系。 我正在嘗試在User
和Role
之間建立一個ManyToMany關系,然后在Role
和Permission
之間建立另一個ManyToMany關系。 我一直都在關注該文章,但似乎出現了此錯誤,無法弄清它為什么會發生。
注意:我使用的是Gradle,而不是Maven; 我不知道那有什么區別。 我還在org.springframework.data.repository.CrudRepository
使用持久性。
2016-06-23 11:35:17.312 ERROR 7389 --- [ main] o.s.boot.SpringApplication : Application startup failed
java.lang.IllegalStateException: Failed to execute ApplicationRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:701)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:688)
at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:678)
Exception in thread "main" at org.springframework.boot.SpringApplication.doRun(SpringApplication.java:343)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:273)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:971)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:960)
at AdeyTrack.AdeyTrackApplication.main(AdeyTrackApplication.java:30)
Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: AdeyTrack.domain.Permissions; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: AdeyTrack.domain.Permissions
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:276)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:221)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:121)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy85.save(Unknown Source)
at AdeyTrack.AdeyTrackApplication.createRoleIfNotFound(AdeyTrackApplication.java:112)
at AdeyTrack.AdeyTrackApplication.run(AdeyTrackApplication.java:76)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:698)
... 7 common frames omitted
Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: AdeyTrack.domain.Permissions
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:139)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:801)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:794)
at org.hibernate.jpa.event.internal.core.JpaPersistEventListener$1.cascade(JpaPersistEventListener.java:97)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:350)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:293)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)
at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:379)
at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:319)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:296)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:118)
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:470)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:295)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:195)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:126)
at org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:84)
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1181)
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:498)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:291)
at com.sun.proxy.$Proxy78.persist(Unknown Source)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:439)
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:498)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:452)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:437)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:409)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61)
java.lang.IllegalStateException: Failed to execute ApplicationRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:701)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:688)
at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:678)
at org.springframework.boot.SpringApplication.doRun(SpringApplication.java:343)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:273)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:971)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:960)
at AdeyTrack.AdeyTrackApplication.main(AdeyTrackApplication.java:30)
Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: AdeyTrack.domain.Permissions; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: AdeyTrack.domain.Permissions
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:276)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:221)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:121)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy85.save(Unknown Source)
at AdeyTrack.AdeyTrackApplication.createRoleIfNotFound(AdeyTrackApplication.java:112)
at AdeyTrack.AdeyTrackApplication.run(AdeyTrackApplication.java:76)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:698)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
... 7 more at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
... 17 common frames omitted
Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: AdeyTrack.domain.Permissions
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:139)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:801)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:794)
at org.hibernate.jpa.event.internal.core.JpaPersistEventListener$1.cascade(JpaPersistEventListener.java:97)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:350)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:293)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)
at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:379)
at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:319)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:296)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:118)
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:470)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:295)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:195)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:126)
at org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:84)
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1181)
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:498)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:291)
at com.sun.proxy.$Proxy78.persist(Unknown Source)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:439)
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:498)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:452)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:437)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:409)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
... 17 more
ApplicationRunner:
package AdeyTrack;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import AdeyTrack.domain.Role;
import AdeyTrack.domain.Permissions;
import AdeyTrack.domain.User;
import AdeyTrack.persistence.repository.PermissionsRepository;
import AdeyTrack.persistence.repository.RoleRepository;
import AdeyTrack.persistence.repository.UserRepository;
@SpringBootApplication
public class AdeyTrackApplication implements ApplicationRunner {
boolean setup = false;
public static void main(String[] args) {
SpringApplication.run(AdeyTrackApplication.class, args);
}
@Autowired
private UserRepository userRepo;
@Autowired
private PermissionsRepository permRepo;
@Autowired
private RoleRepository roleRepo;
@Override
public void run(ApplicationArguments args) throws Exception {
BCryptPasswordEncoder pe = new BCryptPasswordEncoder();
if(setup){ return ; }
/* Create permissions */
Permissions edit_store = createPermissionsIfNotFound(Permission.STORE.PERM_STORE_EDIT.name(), "edit a store");
Permissions create_store = createPermissionsIfNotFound(Permission.STORE.PERM_STORE_CREATE.name(), "create a store");
List<Permissions> adminPermissions = Arrays.asList(edit_store, create_store);
/* Create roles */
createRoleIfNotFound("STORE_ADMIN", adminPermissions);
createRoleIfNotFound("STORE_EDITOR", Arrays.asList(create_store));
Role adminRole = roleRepo.findByRole("STORE_ADMIN");
Role editRole = roleRepo.findByRole("STORE_EDITOR");
User storeadmin = new User("storeadmin", pe.encode("password"));
User storeedit = new User("storeedit", pe.encode("password"));
storeadmin.setRoles(Arrays.asList(adminRole));
storeedit.setRoles(Arrays.asList(editRole));
userRepo.save(storeadmin);
// userRepo.save(storeedit);
setup = true;
}
@Transactional
private Permissions createPermissionsIfNotFound(String name, String description){
Permissions permission = permRepo.findByPermission(name);
if(permission == null){
permission = new Permissions(name, description);
permRepo.save(permission);
}
return permission;
}
@Transactional
private Role createRoleIfNotFound(String name, Collection<Permissions> permissions) {
Role role = roleRepo.findByRole(name);
if (role == null) {
role = new Role(name);
role.setPermissions(permissions);
roleRepo.save(role);
}
return role;
}
}
User.java
package AdeyTrack.domain;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
@Entity
@Table(name="users")
public class User {
@Id
@GeneratedValue
private Integer id;
private String login;
private String password;
private boolean enabled;
@ManyToMany(cascade = {CascadeType.ALL})
@JoinTable(name="users_roles",
joinColumns = {@JoinColumn(name="user_id", referencedColumnName="id")},
inverseJoinColumns = {@JoinColumn(name="role_id", referencedColumnName="id")}
)
private Collection<Role> roles = new ArrayList<>();
public User(){
super();
}
public User(String login, String password){
super();
this.login = login;
this.password = password;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Collection<Role> getRoles() {
return roles;
}
public void setRoles(Collection<Role> role) {
this.roles = role;
}
public void setRole(Role role) {
this.roles.add(role);
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}
角色.java
package AdeyTrack.domain;
import java.util.ArrayList;
import java.util.Collection;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
@Entity
@Table(name="roles")
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String role;
@ManyToMany(mappedBy = "roles")
private Collection<User> users;
@ManyToMany(cascade = {CascadeType.ALL})
@JoinTable(name="role_permissions",
joinColumns = {@JoinColumn(name="role_id", referencedColumnName="id")},
inverseJoinColumns = {@JoinColumn(name="permission_id", referencedColumnName="id")}
)
private Collection<Permissions> rolePermissions;
public Role(){
super();
}
public Role(String role){
super();
this.role = role;
}
public Role(String role, Collection<Permissions> permissions){
super();
this.role = role;
this.rolePermissions = permissions;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public void setUsers(Collection<User> users){
if(users.size() == 1){
this.users = users;
} else if(users.size() > 1){
this.users.addAll(users);
}
}
public Collection<User> getUsers(){
return users;
}
public void setPermissions(Collection<Permissions> permissions){
this.rolePermissions = permissions;
}
public Collection<Permissions> getPermissions(){
return rolePermissions;
}
}
Permission.java
package AdeyTrack.domain;
import java.util.ArrayList;
import java.util.Collection;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name="permissions")
public class Permissions {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@ManyToMany(mappedBy = "rolePermissions", cascade = CascadeType.ALL)
private Collection<Role> roles;
private String permission;
private String description;
public Permissions(){
super();
}
public Permissions(String permission, String description){
super();
this.permission = permission;
this.description = description;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Collection<Role> getRole() {
return roles;
}
public void setRole(Collection<Role> role) {
this.roles = role;
}
public String getPermission(){
return permission;
}
public void setPermission(String permission){
this.permission = permission;
}
public String getDescription(){
return description;
}
public void setDescription(String description){
this.description = description;
}
}
任何幫助,將不勝感激。
通過使用@Transactional,可以自動處理許多重要方面,例如事務傳播。 在這種情況下,如果businessLogic()
調用了另一個事務方法,則該方法可以選擇加入正在進行的事務。
@Transactional
public void businessLogic() {
... use entity manager inside a transaction ...
}
潛在的不利之處在於,這種強大的機制隱藏了幕后發生的事情,從而在無法正常工作時很難進行調試。
@Transactional
的關鍵點之一是要考慮兩個單獨的概念,每個概念都有自己的范圍和生命周期:
the persistence context the database transaction
事務注釋本身定義了單個數據庫事務的范圍。 數據庫事務在持久性上下文的范圍內發生。
持久性上下文在JPA中是EntityManager ,使用Hibernate Session在內部實現(當使用Hibernate作為持久性提供程序時)。
持久性上下文只是一個同步器對象,該對象跟蹤一組有限的Java對象的狀態,並確保最終將這些對象上的更改持久化回到數據庫中。
這與數據庫事務的概念非常不同。 一個實體管理器可用於多個數據庫事務 ,而實際上經常是這樣。
所以我感到非常愚蠢,因為整個問題都在於應用程序運行器。 在進行了更多挖掘之后,我發現在run
方法中使用@Transactional
非常重要,我不知道為什么會這樣,但僅添加注釋已修復了某些原因。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.