0

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 throwed exception java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not Marked cascade 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 org.eclipse.persistence.internal.jpa.EntityManagerImpl.flush(EntityManagerImpl.java:780) の .sessions.RepeatableWriteUnitOfWork.writeChanges(RepeatableWriteUnitOfWork.java:433) 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. com.dao の dao.BasicDAO.findAll(BasicDAO.java:92)。

私が想像する唯一の解決策は、1 つのトランザクション内でプロジェクトを作成し、別のトランザクション内でその権利を個別に保存することです。それが唯一の解決策ですか、それとも別の提案がありますか?

4

1 に答える 1

0

永続化されなかったオブジェクトは? 完全な例外を含めます。

プロジェクトを永続化する前に、オブジェクトとの関係をカスケード永続化としてマークするか、オブジェクトで永続化を呼び出す必要があります。

于 2013-06-12T14:08:40.687 に答える