我有一个使用 JPA (EclipseLink) 和 Spring 框架的 Java EE 应用程序。
在我添加 Spring 事务管理之前,我的持久性类中的一切都运行良好。我有以下实体(对应于数据库表):
项目
@Entity @Table(name="projet") public class Projet implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="id_projet", unique=true, nullable=false) private Integer idProjet; @Column(name="nom_projet") private String nomProjet; /** The projet util droits. */ @OneToMany(mappedBy="projet", cascade={CascadeType.ALL}) private Set<ProjetUtilDroit> projetUtilDroits; public Projet() { } ... }
用户
@Entity @Table(name="utilisateur") public class Utilisateur implements Serializable { /** The Constant serialVersionUID. */ private static final long serialVersionUID = 1L; /** The id utilisateur. */ @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="id_utilisateur", unique=true, nullable=false) private Integer idUtilisateur; /** The nom utilisateur. */ @Column(name="nom_utilisateur", nullable=false, length=50) private String nomUtilisateur; //bi-directional many-to-one association to ProjetUtilDroit /** The projet util droits. */ @OneToMany(mappedBy="utilisateur", cascade={CascadeType.REMOVE}) private Set<ProjetUtilDroit> projetUtilDroits; ... }
正确的
@Entity @Table(name="droit") public class Droit implements Serializable { /** The Constant serialVersionUID. */ private static final long serialVersionUID = 1L; /** The id droit. */ @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="id_droit", unique=true, nullable=false) private Integer idDroit; /** The type droit. */ @Column(name="type_droit", nullable=false, length=10) private String typeDroit; /** * Instantiates a new droit. */ public Droit() { } ... }
以及将用户链接到具有特定权限的项目的关联 (ProjectUserRight)
@Entity @Table(name="projet_util_droit") public class ProjetUtilDroit implements Serializable { /** The Constant serialVersionUID. */ private static final long serialVersionUID = 1L; /** The id. */ @EmbeddedId private ProjetUtilDroitPK id; //bi-directional many-to-one association to Droit /** The droit. */ @ManyToOne(cascade={CascadeType.MERGE, CascadeType.REFRESH}) @JoinColumn(name="id_droit") private Droit droit; //bi-directional many-to-one association to Projet /** The projet. */ @MapsId("idProjet") @ManyToOne(cascade={CascadeType.MERGE, CascadeType.REFRESH}) @JoinColumn(name="id_projet") private Projet projet; //bi-directional many-to-one association to Utilisateur /** The utilisateur. */ @MapsId("idUtilisateur") @ManyToOne(cascade={CascadeType.MERGE, CascadeType.REFRESH}) @JoinColumn(name="id_utilisateur") private Utilisateur utilisateur; ... }
关联的嵌入 ID:
@Embeddable public class ProjetUtilDroitPK implements Serializable { //default serial version id, required for serializable classes. /** The Constant serialVersionUID. */ private static final long serialVersionUID = 1L; /** The id projet. */ @Column(name="id_projet", unique=true, nullable=false) private Integer idProjet; /** The id utilisateur. */ @Column(name="id_utilisateur", unique=true, nullable=false) private Integer idUtilisateur; ... }
我用它的权利创建项目的方法:
public Projet createProject(String name, int idRight, int idUser) {
Projet project = new Projet();
project.setNomProjet(name);
ProjetUtilDroit pud = new ProjetUtilDroit();
Droit d = rightDao.findById(idRight);
pud.setDroit(d);
pud.setProjet(project);
Utilisateur user = userDao.findById(idUser);
pud.setUtilisateur(user);
if(user.getProjetUtilDroits() == null)
user.setProjetUtilDroits(new HashSet<ProjetUtilDroit>());
user.getProjetUtilDroits().add(pud);
Set<ProjetUtilDroit> pudSet = new HashSet<ProjetUtilDroit>();
pudSet.add(pud);
project.setProjetUtilDroits(pudSet);
project = projectDao.create(project);
return project;
}
它就像一个魅力(保留项目和相关的用户权限),直到我在“createProject”方法上方添加注释@Transactionnal......
现在我收到此错误: Avertissement: StandardWrapperValve[dispatcher]: PWC1406: Servlet.service() for servlet dispatcher throw exception java.lang.IllegalStateException: 在同步期间,通过未标记为级联 PERSIST 的关系找到了一个新对象: * * ***项目正确* *** 用户名:userName 权利:阅读。org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.discoverUnregisteredNewObjects(RepeatableWriteUnitOfWork.java:304) org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.calculateChanges(UnitOfWorkImpl.java:702) org.eclipse.persistence.internal .sessions.RepeatableWriteUnitOfWork.writeChanges(RepeatableWriteUnitOfWork.java:433) 在 org.eclipse.persistence.internal.jpa.EntityManagerImpl.flush(EntityManagerImpl.java:780) 在 org.eclipse.persistence.internal.jpa.EJBQueryImpl.performPreQueryFlush(EJBQueryImpl .java:1298) 在 org.eclipse.persistence.internal.jpa.EJBQueryImpl.executeReadQuery(EJBQueryImpl.java:434) 在 org.eclipse.persistence.internal.jpa.EJBQueryImpl.getResultList(EJBQueryImpl.java:742) 在 com。 dao.BasicDAO.findAll(BasicDAO.java:92) 在 com.dao。
我想的唯一解决方案是在一个事务中创建项目并在另一个事务中单独保存其权利。这是唯一的解决方案还是有人有其他建议?