Sto riscontrando un problema nel mappare un attributo incorporato di una classe. Ho creato alcune classi che sono simili a ciò che sto cercando di fare per illustrare. Fondamentalmente, ho una gerarchia di classi @Embeddable che utilizza l'ereditarietà. La classe di livello superiore "Numero parte" ha un solo attributo e le classi estendenti non aggiungono attributi alla classe "Numero parte", aggiungono solo alcune convalida/logica.JPA/Hibernate - Incorporamento di un attributo
Ecco cosa intendo:
PARTE
@Entity
@Table(name="PART")
public class Part {
private Integer id;
private String name;
private PartNumber partNumber;
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name="PART_NAME")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Embedded
public PartNumber getPartNumber() {
return partNumber;
}
public void setPartNumber(PartNumber partNumber) {
this.partNumber = partNumber;
}
}
PARTNUMBER
@Embeddable
public abstract class PartNumber {
protected String partNumber;
private String generalPartNumber;
private String specificPartNumber;
private PartNumber() {
}
public PartNumber(String partNumber) {
this.partNumber = partNumber;
}
@Column(name = "PART_NUMBER")
public String getPartNumber() {
return partNumber;
}
public void setPartNumber(String partNumber) {
this.partNumber = partNumber;
}
/**
* @param partNumber
* @return
*/
public boolean validate(String partNumber) {
// do some validation
return true;
}
/**
* Returns the first half of the Part Number
*
* @return generalPartNumber
*/
@Transient
public String getGeneralPartNumber() {
return generalPartNumber;
}
/**
* Returns the last half of the Part Number
* which is specific to each Car Brand
*
* @return specificPartNumber
*/
@Transient
public String getSpecificPartNumber() {
return specificPartNumber;
}
}
FORD PARTNUMBER
public class FordPartNumber extends PartNumber {
/**
* Ford Part Number is formatted as 1234-#1234
*
* @param partNumber
*/
public FordPartNumber(String partNumber) {
super(partNumber);
validate(partNumber);
}
/*
* (non-Javadoc)
*
* @see com.test.PartNumber#validate(java.lang.String)
*/
@Override
public boolean validate(String partNumber) {
// do some validation
return true;
}
/*
* (non-Javadoc)
*
* @see com.test.PartNumber#getGeneralPartNumber()
*/
@Override
public String getGeneralPartNumber() {
return partNumber;
}
/*
* (non-Javadoc)
*
* @see com.test.PartNumber#getSpecificPartNumber()
*/
@Override
public String getSpecificPartNumber() {
return partNumber;
}
}
CHEVY PARTNUMBER
public class ChevyPartNumber extends PartNumber {
/**
* Chevy Part Number is formatted as 1234-$1234
*
* @param partNumber
*/
public ChevyPartNumber(String partNumber) {
super(partNumber);
validate(partNumber);
}
/*
* (non-Javadoc)
*
* @see com.test.PartNumber#validate(java.lang.String)
*/
@Override
public boolean validate(String partNumber) {
// do some validation
return true;
}
/*
* (non-Javadoc)
*
* @see com.test.PartNumber#getGeneralPartNumber()
*/
@Override
public String getGeneralPartNumber() {
return partNumber;
}
/*
* (non-Javadoc)
*
* @see com.test.PartNumber#getSpecificPartNumber()
*/
@Override
public String getSpecificPartNumber() {
return partNumber;
}
}
Naturalmente questo non funziona, perché Hibernate ignora la Gerarchia di ereditarietà e non piace il fatto che PartNumber è astratta. C'è un modo per farlo usando JPA o Hibernate Annotations? Ho provato a utilizzare l'annotazione @Interitance JPA.
Non è possibile effettuare il refactoring della parte "PartNumber" della gerarchia perché lo sviluppatore originale vuole essere in grado di estendere PartNumber con N molte classi XXXXPartNumber.
Qualcuno sa se qualcosa del genere farà parte di JPA 2.0 o di una nuova versione di Hibernate?
Per B, conosci qualche buon tutorial per il marshalling/unmarshalling di sottoclassi appropriate usando un tipo di sospensione personalizzato? – systemoutprintln
Hai solo bisogno di implementare l'interfaccia UserType di Hibernate - è ragionevolmente semplice. Ecco un esempio dei documenti di Hibernate: (https://www.hibernate.org/172.html). Nel tuo caso, restituirai PartNumber dal metodo "returnedClass()" e istanzerà dinamicamente la classe discendente appropriata in "nullSafeGet()" in base a un valore memorizzato in una colonna (e ottenuto da ResultSet). – ChssPly76