我有這個物體:
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;
這三個物體繼承了它:
@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;
Let's suppose I have a List<StatementLinesEntity> consist of 2 lines, on line has debitAmount = C and operationNature = Virement and second line has debitAmount = C and operationNature = Espece. My goal is to persist each line in a specific DTYPE. example
first line should be persisted in OperationCreditEntity table DTYPE = Virement and the second should be persisted in OperationCreditEntity table DTYPE = Espece
uj5u.com熱心網友回復:
對我來說,模型應該更像:
@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 實體(可以是它的任何一個子類)的方法。無需直接管理、決議或處理 String operationNature 字串,因為操作型別將決定操作性質。
這可能會更改其他簽名、序列化(例如 JSON),因此如果您不能使用它并且“卡”在現有的 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 存盤庫呼叫 save 以將其放入您正在更改的相同事務背景關系中。另請注意,那些 OperationCreditEntity 子類具有您需要找到自己填寫的方法的資料;我個人認為這些資料可能會與定義/創建 StatementLinesEntity 時可用的資料相關聯,因此應該在那時生成/創建,而不是事后,但這取決于你。
Added just to be complete: Yes, you can access the column used to store discriminator values directly in a base entity class. Nothing stops or prevents you from mapping the column as you would any other database column. For Hibernate, it uses "DTYPE", so
@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;
}
Notice I marked this as insertable/updatable=false though. It is provider specific if it complains about controlling this value in this way; many try to do so with the hope of changing it. Changing an entity 'type' is not supported. A Caterpillar does not become a Butterfly just by changing a string value. Any caches that hold OperationCreditEntity or some specific subclass type aren't magically going to have the object type changed; JPA requires you to delete the entity and create a new instance (of the proper class) for that data, preferably after flushing the delete operation.
Also note, you can query and use Entity Type Expressions (TYPE) without having a column or other mapping for it.
"Select line from OperationCreditEntity operation join operation.statementLine line where TYPE(operation) IN (OperationEspecesEntity, OperationChequeEntity) and line.somethingElse = :someValue"
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/454830.html
