简体   繁体   English

在实体管理器上调用合并后,实体丢失 state

[英]Entity loses state after calling merge on entitymanager

I'm running into a very annoying issue whereby an entity loses its state after the object is merged into the EntityManager.我遇到了一个非常烦人的问题,即在 object 合并到 EntityManager 之后,实体会丢失其 state。

In the application there's a "Dossier" with ExpenditureStatements which has a number of expenditures.在应用程序中有一个带有 ExpenditureStatements 的“档案”,其中包含许多支出。

These expenditures can be (partially) claimed from multiple debtors.这些支出可以(部分)向多个债务人索赔。 An ExpenditureStatementClaim is created for the ExpenditureStatement.为 ExpenditureStatement 创建一个 ExpenditureStatementClaim。 An ExpenditureClaim is created for each Expenditure on the ExpenditureStatement.为 ExpenditureStatement 上的每个 Expenditure 创建一个 ExpenditureClaim。

Both the ExpenditureClaims and the ExpenditureStatementClaim are persisted without any issues. ExpenditureClaim 和 ExpenditureStatementClaim 都保持不变,没有任何问题。 The expenditures however lose their state after the merge on the entitymanager is called: em.merge(dossier).然而,在 entitymanager 上的合并被称为:em.merge(dossier) 后,支出将失去其 state。

However, the data in each expenditure reverts back to its last state in the database.但是,每个支出中的数据会恢复到数据库中的最后一个 state。

I've already tried cascading only top down, i've made changes to equals/hashcode but this didn't change anything.我已经尝试过仅自上而下级联,我已经对 equals/hashcode 进行了更改,但这并没有改变任何东西。

Does anyone have a clue as to what might be causing this issue?有没有人知道可能导致此问题的原因?

Dossier:卷宗:

@Entity
@Table(name = "DOSSIER")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "DOSSIER_TYPE", discriminatorType = DiscriminatorType.STRING, length = 48)
public abstract class Dossier  {

@OneToMany(mappedBy = ExpenditureStatement.PROP_DOSSIER, cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
private List<ExpenditureStatement> expenditureStatements = new ArrayList<ExpenditureStatement>();
}

ExpenditureStatement:支出报表:

@Entity
@Table(name = "EXPENDITURE_STATEMENT")
public class ExpenditureStatement {
@ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.MERGE})
@JoinColumn(name = "DOSSIER_ID", nullable = false)
private Dossier dossier;

@OneToMany(mappedBy = Expenditure.PROP_EXPENDITURE_STATEMENT, cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
private List<Expenditure> expenditures = new ArrayList<Expenditure>();

@OneToMany(mappedBy = ExpenditureStatementClaim.PROP_EXPENDITURE_STATEMENT, cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
private Collection<ExpenditureStatementClaim> expenditureStatementClaims = new ArrayList<ExpenditureStatementClaim>();
}

Expenditure:支出:

@Entity
@Table(name = "EXPENDITURE")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "EXPENDITURE_ORIGIN_CD", discriminatorType = DiscriminatorType.STRING, length = 48)
public abstract class Expenditure extends EntityObject<Long> {

@ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "EXPENDITURE_STATEMENT_ID", nullable = false)
private ExpenditureStatement expenditureStatement;

@OneToMany(mappedBy = ExpenditureClaim.PROP_EXPENDITURE, cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
private Collection<ExpenditureClaim> claims = new HashSet<>();

@NotNull
@Column(name = "EXPENDITURE_STATUS_CD", nullable = false)
@Enumerated(EnumType.STRING)
private ExpenditureStatus status;

public abstract BigDecimal getAmount();
}

ExpenditureStatementClaim: ExpenditureStatementClaim:

@Entity
@Table(name = "DEEL_STAAT")
public class ExpenditureStatementClaim {    

@NotNull
@ManyToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST})
@JoinColumn(name = "EXPENDITURE_STATEMENT_ID", nullable = false)
private ExpenditureStatement expenditureStatement;

@OneToMany(mappedBy = ExpenditureClaim.PROP_EXPENDITURE_STATEMENT_CLAIM, cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
private Collection<ExpenditureClaim> expenditureClaims = new ArrayList<>();

@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name = "INVOICE_ID")
private Invoice invoice;
}

ExpenditureClaim:支出索赔:

@Entity
@Table(name = "EXPENDITURE_CLAIM")
public class ExpenditureClaim extends EntityObject<Long> {

@ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "EXPENDITURE_ID", nullable = false)
private Expenditure expenditure;

@Column(name = "AMOUNT", precision = NumberConstants.CURRENCY_PRECISION, scale = NumberConstants.CURRENCY_OPERATION_SCALE)
private BigDecimal amount;

@ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "EXPENDITURE_ST_CLAIM_ID", nullable = false)
private ExpenditureStatementClaim expenditureStatementClaim;
}

The issue was not caused by a problem with the mapping, but due to a bug in the (quite old) version of EclipseLink the project was using, whereby a newly created object would not cascade changes made to an already existing object.该问题不是由映射问题引起的,而是由于项目使用的(相当旧的)版本的 EclipseLink 中的一个错误,即新创建的 object 不会级联对现有 object 所做的更改。

https://bugs.eclipse.org/bugs/show_bug.cgi?id=340802 https://bugs.eclipse.org/bugs/show_bug.cgi?id=340802

Just a good reminder that whenever possible you should try to update the version of the dependencies in your project...只是一个很好的提醒,只要有可能,您应该尝试更新项目中依赖项的版本......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM