在 entitymanager 上调用合并后实体丢失状态
Entity loses state after calling merge on entitymanager
我 运行 遇到了一个非常烦人的问题,即实体在对象合并到 EntityManager 后会丢失其状态。
在应用程序中有一个 "Dossier" with ExpenditureStatements 其中有一些支出。
这些支出可以(部分)从多个债务人那里索取。
为 ExpenditureStatement 创建一个 ExpenditureStatementClaim。
为 ExpenditureStatement 上的每个支出创建一个 ExpenditureClaim。
ExpenditureClaims 和 ExpenditureStatementClaim 均已保留,没有任何问题。
然而,在调用 entitymanager 上的合并后,支出会失去其状态:
em.merge(档案)。
但是,每笔支出中的数据都会恢复到其在数据库中的最后状态。
我已经尝试过仅自上而下的级联,我已经对 equals/hashcode 进行了更改,但这并没有改变任何东西。
有人知道可能导致此问题的原因吗?
档案:
@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>();
}
支出报表:
@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>();
}
支出:
@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();
}
支出声明声明:
@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;
}
支出申请:
@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;
}
这个问题不是由映射问题引起的,而是由于项目使用的(相当旧的)EclipseLink 版本中的错误,因此新创建的对象不会级联对已经存在的对象所做的更改对象。
https://bugs.eclipse.org/bugs/show_bug.cgi?id=340802
一个很好的提醒,只要有可能,您应该尝试更新项目中依赖项的版本...
我 运行 遇到了一个非常烦人的问题,即实体在对象合并到 EntityManager 后会丢失其状态。
在应用程序中有一个 "Dossier" with ExpenditureStatements 其中有一些支出。
这些支出可以(部分)从多个债务人那里索取。 为 ExpenditureStatement 创建一个 ExpenditureStatementClaim。 为 ExpenditureStatement 上的每个支出创建一个 ExpenditureClaim。
ExpenditureClaims 和 ExpenditureStatementClaim 均已保留,没有任何问题。 然而,在调用 entitymanager 上的合并后,支出会失去其状态: em.merge(档案)。
但是,每笔支出中的数据都会恢复到其在数据库中的最后状态。
我已经尝试过仅自上而下的级联,我已经对 equals/hashcode 进行了更改,但这并没有改变任何东西。
有人知道可能导致此问题的原因吗?
档案:
@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>();
}
支出报表:
@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>();
}
支出:
@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();
}
支出声明声明:
@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;
}
支出申请:
@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;
}
这个问题不是由映射问题引起的,而是由于项目使用的(相当旧的)EclipseLink 版本中的错误,因此新创建的对象不会级联对已经存在的对象所做的更改对象。
https://bugs.eclipse.org/bugs/show_bug.cgi?id=340802
一个很好的提醒,只要有可能,您应该尝试更新项目中依赖项的版本...