Jpa datanucleus EntityManager合并正在插入新行而不是更新
CustomerSurvey.javaJpa 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(
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();
}