Java 持久化已关联使用@idclass的实体列表的实体

Java 持久化已关联使用@idclass的实体列表的实体,java,hibernate,jpa,primefaces,ejb,Java,Hibernate,Jpa,Primefaces,Ejb,我有一个评估实体,它有一个EvaluationEvaluator的关联列表。我需要显式创建该实体,因为它需要一个额外的列状态。在我继续评估之前。I do:evaluation.setEvaluationEvaluatorlistEvaluator,其中listEvaluator是EvaluationEvaluator类型的列表。然后进行评估。当我运行它时,它不会抛出任何类型的异常。但在数据库中,它插入到评估表中,而不是插入到EvaluationEvaluator表中 下面是我的评估实体 @Ent

我有一个评估实体,它有一个EvaluationEvaluator的关联列表。我需要显式创建该实体,因为它需要一个额外的列状态。在我继续评估之前。I do:evaluation.setEvaluationEvaluatorlistEvaluator,其中listEvaluator是EvaluationEvaluator类型的列表。然后进行评估。当我运行它时,它不会抛出任何类型的异常。但在数据库中,它插入到评估表中,而不是插入到EvaluationEvaluator表中

下面是我的评估实体

@Entity
public class Evaluation implements Serializable{
      @Id
      @GeneratedValue
      private Long id;

      //MORE FIELDS

      @OneToMany(mappedBy="evaluation")
      private List<EvaluationEvaluator> evaluators;

      //CONSTRUCTORS
      //GETTER AND SETTERS
}
这是我的EvaluationEvaluatorId类

public class EvaluationEvaluatorId implements Serializable{
    private Long employeeID;
    private Long evaluationID;

    //CONSTRUCTOR
    //GETTER AND SETTERS
}
最后,这是我的EvaluationBean类

@Stateful
@Named
@LocalBean
@ConversationScoped
public class EvaluationBean {
   @PersistentContext(type= PersistenceContextType.EXTENDED)
   private EntityManager em;

   @Inject
   Conversation conversation;  

   private Evaluation evaluation;

   //IN MY WEBPAGE I IMPLEMENT PRIMEFACES PICKLIST AND IT REQUIRE DUALIST TO HANDLE
   private DualListModel<Employe> evaluators;

   private EvaluationEvaluator evaluationEvaluator;

   private List<EvaluationEvaluator> listEvaluators;

   @Inject
   private EmployeeList employeeList;

   //GETTER AND SETTERS

   public String begin(){
      if (conversation.isTransient()){
          converstaion.begin();
      }
      evaluationEvaluator = new EvaluationEvaluator();
      listEvaluators = new ArrayList<EvaluationEvaluator>();
      evaluation = new Evaluation();
      List<Employee> source = employeeList.findAll();
      target = new ArrayList<Employee>();
      evaluators = new DualListModel<Employee>(source, target);
      return "/evalution/evaluationAsig.xhtml"
   }
    public String save(){
        Iterator<Employee> iterator = evaluators.getTarget().iterator();
        while (iterator.hasNext()){
            EvaluationEvaluator ev = new EvaluationEvaluator();
            ev.setEmployee(iterator.next());
            listEvaluators.add(ev);
        }
        evalution.setEvaluationEvaluators(listEvaluators);
        if(evaluation.getId()==null){
           em.persist(evalution); 
        } else{
           em.merge(evalution);
        }
        if(!conversation.isTransient()){
           convesation.end();
        }
        return "/evalution/evaluationsAsig.xhtml"
    }
}
当我调试我的应用程序时,显然一切都是正确的,但我上面提到的,并没有持续存在于EvaluationEvaluator表中。

您的@OneToMany关联缺少级联配置

将cascade=CascadeType.ALL或cascade={CascadeType.PERSIST,CascadeType.MERGE}添加到@OneToMany注释中。JPA默认假定没有级联,因此您需要自己明确地持久化每个EvaluationEvaluator

使现代化 代码还有一个问题-EvaluationEvaluator的ID从未分配。您有一个由两个长列组成的复杂键。两者都被标记为不可插入或不可更新,这告诉JPA该id将以某种方式在数据库级别生成,它不应该关心它。然而,您的实体中没有明确配置的序列,尽管它不一定是必需的,并且也来自您的注释:


我按照你的建议做了,但它引发了以下异常。具有相同标识符的不同对象已与会话关联


我假设情况并非如此,两个id列值都默认为null或零,并且对于您尝试持久化的所有EvaluationEvaluator都是相同的。如果您希望数据库自动生成id,请使用@GeneratedValue——在这里您可以找到如何执行此操作的说明。数据库部分依赖于数据库,这是针对PostgreSQL的。然而,最常见的用例是配置序列,但让hibernate选择下一个值,这里的说明-

谢谢,快速回答。那么这样做就没有意义了,对吧?listEvaluators.addev;我只是这样做:虽然iterator.hasNext{EvaluationEvaluator ev=new EvaluationEvaluator;ev.setEmployeeiterator.next;em.persistenev.}将EvaluationEvaluators添加到评估中正在创建实际的关联,但您仍然需要这样做。但是级联只是意味着当你持久化根时,所有的实体都被持久化在一起。具有相同标识符的另一个对象已与会话关联。我知道这是与内存相关的会话的问题,但我找不到它,我尝试在持久化该对象之前使用清除方法,但不起作用。不明白我做错了什么。提前感谢此异常表示已在entity manager中注册了具有相同id的实体。您可以将其视为试图存储具有相同ID的两行。我会更新更多细节的答案。。。
@Stateful
@Named
@LocalBean
@ConversationScoped
public class EvaluationBean {
   @PersistentContext(type= PersistenceContextType.EXTENDED)
   private EntityManager em;

   @Inject
   Conversation conversation;  

   private Evaluation evaluation;

   //IN MY WEBPAGE I IMPLEMENT PRIMEFACES PICKLIST AND IT REQUIRE DUALIST TO HANDLE
   private DualListModel<Employe> evaluators;

   private EvaluationEvaluator evaluationEvaluator;

   private List<EvaluationEvaluator> listEvaluators;

   @Inject
   private EmployeeList employeeList;

   //GETTER AND SETTERS

   public String begin(){
      if (conversation.isTransient()){
          converstaion.begin();
      }
      evaluationEvaluator = new EvaluationEvaluator();
      listEvaluators = new ArrayList<EvaluationEvaluator>();
      evaluation = new Evaluation();
      List<Employee> source = employeeList.findAll();
      target = new ArrayList<Employee>();
      evaluators = new DualListModel<Employee>(source, target);
      return "/evalution/evaluationAsig.xhtml"
   }
    public String save(){
        Iterator<Employee> iterator = evaluators.getTarget().iterator();
        while (iterator.hasNext()){
            EvaluationEvaluator ev = new EvaluationEvaluator();
            ev.setEmployee(iterator.next());
            listEvaluators.add(ev);
        }
        evalution.setEvaluationEvaluators(listEvaluators);
        if(evaluation.getId()==null){
           em.persist(evalution); 
        } else{
           em.merge(evalution);
        }
        if(!conversation.isTransient()){
           convesation.end();
        }
        return "/evalution/evaluationsAsig.xhtml"
    }
}