php - haslifecyclecallbacks - single table table per class joined
¿Puede una columna Discriminator ser parte de la clave principal en Doctrine2? (2)
No se puede, la columna de descriminador no se puede usar como parte de la clave principal.
¿Por qué necesita STI para este caso de uso por cierto? Tienes que crear una nueva clase por cada servicio de identificación abierta que proporciones, suena bastante molesto :-)
Estoy usando herencia de tabla única en Doctrine2 para almacenar credenciales de OAuth para servicios múltiples. Me gustaría usar la identificación del servicio como la clave principal; sin embargo, eso no es único en todos los servicios.
Configuré la base de datos para usar la columna del discriminador y la identificación del servicio como la clave principal, pero no puedo encontrar la forma de que Doctrine utilice la columna del discriminador como clave (además de la columna del discriminador). Estoy usando anotaciones de docblock, y si agrego la columna del discriminador como un campo @Id recibo un error:
Duplicate definition of column...in a field or discriminator column mapping.
Si solo defino el campo como la columna del discriminador, los identificadores del servicio superpuestos actualizan todas las filas coincidentes.
De todos modos para hacer que esto funcione, que no sea simplemente usar un valor autogenerado por él?
Para aquellos que usan Hibernate, pueden (al menos a partir de JPA 2.1). El siguiente código perfecclty funciona en mi entorno (hibernate-entitymanager 4.3.6.Final):
@Entity
@Table(name = "CODIFICATIONS")
@IdClass(CodificationId.class)
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = Codification.DISCRIMINATOR_COLUMN, discriminatorType = DiscriminatorType.INTEGER)
public abstract class Codification implements Serializable {
public static final String DISCRIMINATOR_COLUMN = "TABLE_ID";
private static final long serialVersionUID = 1L;
@Column(name = "CODIFICATION_ID")
protected Long codificationId;
@Id
@Column(name = DISCRIMINATOR_COLUMN, insertable = false, updatable = false)
protected Long tableId;
@Id
@Column(name = "CODE_ID", insertable = false, updatable = false)
protected Long codeId;
@Column(name = "LONG_NAME")
protected String longName;
@Column(name = "SHORT_NAME")
protected String shortName;
}
public class CodificationId implements Serializable {
private static final long serialVersionUID = 1L;
private Long tableId;
private Long codeId;
public Long getTableId() {
return tableId;
}
public void setTableId(Long tableId) {
this.tableId = tableId;
}
public Long getCodeId() {
return codeId;
}
public void setCodeId(Long codeId) {
this.codeId = codeId;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((tableId == null) ? 0 : tableId.hashCode());
result = prime * result + ((codeId == null) ? 0 : codeId.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
CodificationId other = (CodificationId) obj;
if (tableId == null) {
if (other.tableId != null)
return false;
} else if (!tableId.equals(other.tableId))
return false;
if (codeId == null) {
if (other.codeId != null)
return false;
} else if (!codeId.equals(other.codeId))
return false;
return true;
}
}
@Entity
@DiscriminatorValue(Status.DISCRIMINATOR_VALUE)
public class Status extends Codification {
public static final String DISCRIMINATOR_VALUE = "2";
private static final long serialVersionUID = 1L;
}
Luego configuro una asociación para el estado con el siguiente código:
@ManyToOne
@JoinColumnsOrFormulas({
@JoinColumnOrFormula(formula = @JoinFormula(referencedColumnName = Codification.DISCRIMINATOR_COLUMN, value = Status.DISCRIMINATOR_VALUE)),
@JoinColumnOrFormula(column = @JoinColumn(name = "STATUS", referencedColumnName = "CODE_ID")) })
private Status status;