【问题标题】:Persist an entity that have associated a list of entities that use @idclass持久化与使用@idclass 的实体列表相关联的实体
【发布时间】:2014-05-19 17:36:57
【问题描述】:

我有一个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 表中。

【问题讨论】:

    标签: java hibernate jpa primefaces ejb


    【解决方案1】:

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

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


    更新

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

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

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

    【讨论】:

    • 感谢您的快速回答。那么这样做是没有意义的,对吧? listEvaluators.add(ev);我只是这样做: while (iterator.hasNext()){ EvaluationEvaluator ev = new EvaluationEvaluator(); ev.setEmployee(iterator.next()); em.persist(ev)。 }
    • EvaluationEvaluators 添加到 Evaluation 是创建实际关联,您仍然需要这样做。但是级联只是意味着当你持久化根时所有实体都被持久化在一起。
    • 我按照您的建议做了,但它引发了以下异常。 “具有相同标识符的不同对象已与会话相关联”我知道这是与内存相关的会话有问题但我找不到它,我尝试在持久化对象之前使用方法 clear () 但没有工作.不明白我做错了什么。在此先感谢
    • 这个异常意味着实体管理器中已经注册了一个相同id的实体。您可以将其视为您尝试存储具有相同 ID 的两行。我会用更多细节更新答案...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-02
    • 2016-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多