Spring 引导:如何将数据保存到特定的 DTYPE
Spring boot: How to Save data to specific DTYPE
我有这个实体:
public class StatementLinesEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long statementLinesId;
@CreationTimestamp
@Temporal(TemporalType.DATE)
private Date dateOperation;
private String operationNature;
private BigDecimal amount;
private String debitAmount;
并且此实体具有 SINGLE_TABLE 类型的继承:
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class OperationCreditEntity {
@Id
@Column(nullable = false, updatable = false)
@GeneratedValue(strategy = GenerationType.AUTO)
private Long operationCreditId;
@CreatedDate
private Date operationDate;
@OneToOne
private StatementLinesEntity statementLine;
这 3 个实体继承了它:
@Entity
@DiscriminatorValue("Espece")
public class OperationEspecesEntity extends OperationCreditEntity {
private String cin;
private String nomEmetteur;
private String prenomEmetteur;
=============================
@DiscriminatorValue("Virement")
public class OperationVirementEntity extends OperationCreditEntity {
private String rib;
===========================
@Entity
@DiscriminatorValue("Cheque")
public class OperationChequeEntity extends OperationCreditEntity{
private int numeroCheque;
假设我有一个由两行组成的 List<StatementLinesEntity>
,第一行有 debitAmount = C
和 operationNature = Virement
,第二行有 debitAmount = C
和 operationNature = Espece
。我的目标是在特定 DTYPE
中坚持每一行。例子
第一行应保留在 OperationCreditEntity table DTYPE = Virement
中,第二行应保留在 OperationCreditEntity table DTYPE = Espece
中
我的模型应该更像是:
@Entity
public class StatementLinesEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long statementLinesId;
@CreationTimestamp
@Temporal(TemporalType.DATE)
private Date dateOperation;
@OneToOne(mappedBy = "statementLine")
private OperationCreditEntity operation;
private BigDecimal amount;
private String debitAmount;
}
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
abstract public class OperationCreditEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long operationCreditId;
@CreatedDate
private Date operationDate;
@OneToOne
private StatementLinesEntity statementLine;
}
任何采用 StatementLinesEntity 实例的方法都可以采用引用 OperationCreditEntity 实例(可以是其子classes 之一)的方法。无需直接管理、解析或处理String operationNature字符串,操作类型决定操作性质
这可能会改变其他签名、序列化(例如 JSON),因此如果您不能使用它并且 'stuck' 与您现有的 StatementLinesEntity 数据表示形式,您需要处理如何从该数据创建您的 OperationCreditEntity 实例。没有工具可以自动为您完成。它就像以下形式的实用程序一样简单:
OperationCreditEntity createOperationInstance(StatementLinesEntity statementLine) {
String operationNature = statementLine.getOperationNature();
OperationCreditEntity returnVal = null;
if "Espece".equals(operationNature) {
returnVal = new OperationEspecesEntity();
} else if "Virement".equals(operationNature) {
returnVal = new OperationVirementEntity();
} else if "Cheque".equals(operationNature) {
returnVal = new OperationChequeEntity();
} else {
throw new IllegalStateException();
}
returnVal.setStatementLine(statementLine);
return returnVal;
}
当您调用此方法时,只需使用您的 OperationCreditEntity 存储库调用保存,即可将其放入您正在更改的同一事务上下文中。另请注意,那些 OperationCreditEntity subclasses 具有您需要找到自己填写的方法的数据;我个人认为此数据可能与 defining/creating StatementLinesEntity 时可用的数据相关联,因此应该是 generated/created,而不是事后,但这取决于您。
添加只是为了完整:
是的,您可以直接在基本实体 class 中访问用于存储鉴别器值的列。没有什么能阻止或阻止您像映射任何其他数据库列那样映射该列。对于 Hibernate,它使用“DTYPE”,所以
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class OperationCreditEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long operationCreditId;
@CreatedDate
private Date operationDate;
@Column(name="DTYPE",insertable=false, updatable=false)
private String typeValue;
}
请注意,我将此标记为 insertable/updatable=false。如果它抱怨以这种方式控制此值,则它是特定于提供者的;许多人试图这样做,希望能改变它。不支持更改实体 'type'。 Caterpillar 不会仅仅通过更改字符串值就变成 Butterfly。任何包含 OperationCreditEntity 或某些特定 subclass 类型的缓存都不会神奇地更改对象类型; JPA 要求您删除实体并为该数据创建一个新实例(正确的 class),最好是在刷新删除操作之后。
另请注意,您可以在没有列或其他映射的情况下查询和使用实体类型表达式 (TYPE)。
"Select line from OperationCreditEntity operation join operation.statementLine line where TYPE(operation) IN (OperationEspecesEntity, OperationChequeEntity) and line.somethingElse = :someValue"
我有这个实体:
public class StatementLinesEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long statementLinesId;
@CreationTimestamp
@Temporal(TemporalType.DATE)
private Date dateOperation;
private String operationNature;
private BigDecimal amount;
private String debitAmount;
并且此实体具有 SINGLE_TABLE 类型的继承:
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class OperationCreditEntity {
@Id
@Column(nullable = false, updatable = false)
@GeneratedValue(strategy = GenerationType.AUTO)
private Long operationCreditId;
@CreatedDate
private Date operationDate;
@OneToOne
private StatementLinesEntity statementLine;
这 3 个实体继承了它:
@Entity
@DiscriminatorValue("Espece")
public class OperationEspecesEntity extends OperationCreditEntity {
private String cin;
private String nomEmetteur;
private String prenomEmetteur;
=============================
@DiscriminatorValue("Virement")
public class OperationVirementEntity extends OperationCreditEntity {
private String rib;
===========================
@Entity
@DiscriminatorValue("Cheque")
public class OperationChequeEntity extends OperationCreditEntity{
private int numeroCheque;
假设我有一个由两行组成的 List<StatementLinesEntity>
,第一行有 debitAmount = C
和 operationNature = Virement
,第二行有 debitAmount = C
和 operationNature = Espece
。我的目标是在特定 DTYPE
中坚持每一行。例子
第一行应保留在 OperationCreditEntity table DTYPE = Virement
中,第二行应保留在 OperationCreditEntity table DTYPE = Espece
我的模型应该更像是:
@Entity
public class StatementLinesEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long statementLinesId;
@CreationTimestamp
@Temporal(TemporalType.DATE)
private Date dateOperation;
@OneToOne(mappedBy = "statementLine")
private OperationCreditEntity operation;
private BigDecimal amount;
private String debitAmount;
}
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
abstract public class OperationCreditEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long operationCreditId;
@CreatedDate
private Date operationDate;
@OneToOne
private StatementLinesEntity statementLine;
}
任何采用 StatementLinesEntity 实例的方法都可以采用引用 OperationCreditEntity 实例(可以是其子classes 之一)的方法。无需直接管理、解析或处理String operationNature字符串,操作类型决定操作性质
这可能会改变其他签名、序列化(例如 JSON),因此如果您不能使用它并且 'stuck' 与您现有的 StatementLinesEntity 数据表示形式,您需要处理如何从该数据创建您的 OperationCreditEntity 实例。没有工具可以自动为您完成。它就像以下形式的实用程序一样简单:
OperationCreditEntity createOperationInstance(StatementLinesEntity statementLine) {
String operationNature = statementLine.getOperationNature();
OperationCreditEntity returnVal = null;
if "Espece".equals(operationNature) {
returnVal = new OperationEspecesEntity();
} else if "Virement".equals(operationNature) {
returnVal = new OperationVirementEntity();
} else if "Cheque".equals(operationNature) {
returnVal = new OperationChequeEntity();
} else {
throw new IllegalStateException();
}
returnVal.setStatementLine(statementLine);
return returnVal;
}
当您调用此方法时,只需使用您的 OperationCreditEntity 存储库调用保存,即可将其放入您正在更改的同一事务上下文中。另请注意,那些 OperationCreditEntity subclasses 具有您需要找到自己填写的方法的数据;我个人认为此数据可能与 defining/creating StatementLinesEntity 时可用的数据相关联,因此应该是 generated/created,而不是事后,但这取决于您。
添加只是为了完整: 是的,您可以直接在基本实体 class 中访问用于存储鉴别器值的列。没有什么能阻止或阻止您像映射任何其他数据库列那样映射该列。对于 Hibernate,它使用“DTYPE”,所以
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class OperationCreditEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long operationCreditId;
@CreatedDate
private Date operationDate;
@Column(name="DTYPE",insertable=false, updatable=false)
private String typeValue;
}
请注意,我将此标记为 insertable/updatable=false。如果它抱怨以这种方式控制此值,则它是特定于提供者的;许多人试图这样做,希望能改变它。不支持更改实体 'type'。 Caterpillar 不会仅仅通过更改字符串值就变成 Butterfly。任何包含 OperationCreditEntity 或某些特定 subclass 类型的缓存都不会神奇地更改对象类型; JPA 要求您删除实体并为该数据创建一个新实例(正确的 class),最好是在刷新删除操作之后。
另请注意,您可以在没有列或其他映射的情况下查询和使用实体类型表达式 (TYPE)。
"Select line from OperationCreditEntity operation join operation.statementLine line where TYPE(operation) IN (OperationEspecesEntity, OperationChequeEntity) and line.somethingElse = :someValue"