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

时间:2014-05-19 17:36:58

标签: java hibernate jpa primefaces ejb

我有一个Evaluation实体,其关联列表为EvaluationEvaluator。我需要显式创建该实体,因为它需要一个额外的列" STATUS"。在我继续评估之前。我这样做:evaluation.setEvaluationEvaluator(listEvaluator)其中listEvaluatorEvaluationEvaluator类型的列表。然后是persist(evaluation)。当我运行它时,它不会抛出任何异常。但是在数据库中,它会插入Evaluation表中,而不会插入到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
}

这是我的EvalutionEvaluator实体:

@Entity
@Table(name= "EVALUATION_EVALUATOR")
@IdClass(EvaluationEvaluatorId.class)
public class EvaluationEvaluator implements Serializable{
    @Id
    @Column(name="EMPLOYEE_ID", insertable=false , updatable=false)
    private Long EmployeeID;
    @Id
    @Column(name="EVALUATION_ID", insertable=false, updatable=false)
    private Long EvaluationID;

    @ManyToOne
    @JoinColumn(name"EMPLOYEE_ID")
    private Employee employee;

    @ManyToOne
    @JoinColumn(name"EVALUATION_ID")
    private Evaluation evaluation;

    @NotNull
    private String status;

    //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表中保留。

1 个答案:

答案 0 :(得分:0)

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

cascade = CascadeType.ALLcascade = {CascadeType.PERSIST, CascadeType.MERGE}添加到@OneToMany注释中。 JPA假定默认情况下没有级联,因此您需要自己明确地保留每个 EvaluationEvaluator


更新

代码还有另一个问题 - 从未分配 EvaluationEvaluators 的ID。您有一个由两个Long列组成的复杂密钥。两者都标记为不可插入或不可更新,这告诉JPA id将以某种方式在数据库级别生成,并且它不应该关心它。但是,您的实体中没有明确配置序列(虽然不一定是必需的),也可能来自您的评论:

  

我做了你推荐的但它引发了以下异常。 “具有相同标识符的不同对象已与会话”

相关联

我认为情况并非如此,并且两个id列值默认为 null ,并且对于所有 EvaluationEvaluators 都是相同的试图坚持下去。如果您希望数据库为您生成id,请自动使用@GeneratedValue - Configure JPA to let PostgreSQL generate the primary key value - 在这里您可以找到解释如何执行此操作(数据库部分依赖于数据库,这适用于PostgreSQL)。然而,最常见的用例是配置序列,但让hibernate选择下一个值,这里有说明 - Hibernate sequence on oracle, @GeneratedValue(strategy = GenerationType.AUTO)