Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jpa datanucleus EntityManager合并正在插入新行而不是更新_Jpa_Merge_Datanucleus - Fatal编程技术网

Jpa datanucleus EntityManager合并正在插入新行而不是更新

Jpa datanucleus EntityManager合并正在插入新行而不是更新,jpa,merge,datanucleus,Jpa,Merge,Datanucleus,CustomerSurvey.java public class CustomerSurvey implements Serializable { /** * */ private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "CUSTOMER_SURVEY_SEQUENCE") @Column(

CustomerSurvey.java

 public class CustomerSurvey
    implements Serializable
 {

/**
 * 
 */
private static final   long  serialVersionUID = 1L;

@Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "CUSTOMER_SURVEY_SEQUENCE") @Column(name = "SURVEYID", nullable = false) private String surveyId;

@ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL) @JoinColumn(name = "CUSTNO", referencedColumnName = "CustNO") private Customer               customer;
@Column(name = "AVGRATINGS") private double                                                                                                                 avgRatings;

@Column(name = "COMMENTS") private String                                                                                                                   comments;

@Column(name = "SENTON") private Date                                                                                                                       sentOn;

@Column(name = "RESPONDEDON") private Date                                                                                                                  respondedOn;

@Column(name = "RESPONDED") int                                                                                                                             responded;
@Basic(fetch = FetchType.EAGER) @OneToMany(mappedBy = "customerSurvey", cascade = CascadeType.ALL) private Set<SurveyResponse>                              responses;

@XmlTransient @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.DETACH) @JoinColumn(name = "SRNO") private ServiceRequest                             serviceRequest;

@Column(name = "ATTACHMENT") @Lob @Basic(fetch = FetchType.EAGER) private byte[]                                                                            attachment;
--- getters and setters---

 public int hashCode()
     {
    return new HashCodeBuilder(17,31)
    .append(this.surveyId)
 //        .append(this.avgRatings)
 //        .append(this.getResponded())
    .toHashCode();

}

@Override
public boolean equals(Object obj)
{

    return new EqualsBuilder().
            append("SurveyId",this.surveyId)
//                .append("responded", this.getResponded())
//                .append("AvgRatings", this.getAvgRatings())
            .isEquals();
}
它不更新,而是插入新行。 在使用hashcode builder和equals builder后,我因以下检查而得到false: System.out.println(“:”+survey.equals(dbSurvey))的测试;给假 系统输出println(survey.equals(cs))的测试; 上面给出了错误的答案


请注意,根据JPA规范,“瞬态”和“分离”是不同的状态,在merge()中具有不同的行为。瞬态将创建一个新对象。已与现有的更新分离。在修改之前获取分离的对象,或者阅读

上的“分离”部分,当传递到“合并”时,对象处于什么状态?这对merge的功能至关重要。当我检查状态时,NucleusJPAHelper.getObjectState(obj)也会告诉您:我看到obj状态:瞬态。我正在使用远程客户端进行呼叫(REST呼叫)。当我从容器内部发出相同的调用时,我看到状态是分离的。谢谢你引导我找到它的状态。。。有没有关于如何处理这个差距的建议?我已经编辑了我的问题。。。我正在使用hashcode builder和equal builder,其中对象比较现在返回false。这有助于处理带有键的瞬态对象。设置datanucleus.allowAttachOfTransient=true是在实体管理器工厂(persistenct)级别完成的。它还影响那些真正瞬态的对象(key为null,实体尚未在db中创建)。它也尝试合并这些对象。如果我只在transient+有一个现有密钥的情况下寻找合并,会怎么样?目前我使用的是:CustomerSurvey refSurvey=em.find(CustomerSurvey.class,survey.getSurveyId());如果((NucleusJPAHelper.getObjectState(survey).equals(“transient”)&&(refSurvey!=null)){…持久性属性的描述非常清楚,显然,在调用merge()时,任何没有id的临时对象都将被持久化没有附上,事实上,我们所有的测试都证明了这一事实,并且回答了您发布的问题
    if ( this.entityManagerFactory == null )
    {
        this.entityManagerFactory = this.getEntityManagerFactory();
    }

    EntityManager em = this.entityManagerFactory.createEntityManager();
    EntityTransaction tx = em.getTransaction();

    for (CustomerSurvey survey : surveys)
    {
        tx.begin();
        survey.setRespondedOn(Calendar.getInstance().getTime());
        survey.setResponded(BooleanResponse.YES.getCode());
        survey.setCustomer(em.find(Customer.class, survey.getCustomer().getCustNo().trim()));
        survey.setComments("Survey Response submitted");
        for (SurveyResponse response : survey.getResponses())
        {
            response.setQuestionair(em.find(Questionair.class, response.getQuestionair().getqNo()));
        }

        CustomerSurvey cs = em.find(CustomerSurvey.class, survey.getSurveyId());
        System.out.println(survey.equals(cs));
        Query query1 = em.createQuery("SELECT  from CustomerSurvey customerSurvey where customerSurvey.surveyId = :id")
                .setParameter("id", survey.getSurveyId());
        CustomerSurvey dbSurvey = (CustomerSurvey) query1.getResultList().get(0);
        System.out.println(":" + survey.equals(dbSurvey));

        if(survey.getServiceRequest() == null) {
            cs = em.find(CustomerSurvey.class, survey.getSurveyId());
            survey.setServiceRequest(cs.getServiceRequest());
        }
        CustomerSurvey mSurvey = em.merge(survey);

        String surveyId = mSurvey.getSurveyId();
        Query query = em.createNamedQuery("surveyResponse.getAverageRatings");
        logger.trace(query.toString());
        query.setParameter("surveyId", surveyId);
        logger.trace(query.toString());

        Double avgRating = (Double) query.getSingleResult();
        if ( avgRating == null )
        {
            avgRating = new Double(0);
        }
        BigDecimal bd = BigDecimal.valueOf(avgRating);
        bd = bd.setScale(2, RoundingMode.HALF_UP);
        avgRating = bd.doubleValue();
        mSurvey.setAvgRatings(avgRating);
        em.flush();
        tx.commit();
   }
    em.clear();
    em.close();
}