Usamos herencia de tabla única para cada tabla en nuestra aplicación. Esto permite que distintas instancias de la misma pila de aplicaciones funcionen con los mismos DAO, mientras que sus entidades pueden diferir ligeramente y potencialmente pueden contener información exclusiva de esa instancia. Una clase abstracta define la estructura básica mesa y una extensión define columnas adicionales, si es necesario por esa instancia:¿Puedo eliminar la columna del discriminador en una herencia de tabla única de Hibernate?
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Table(name = "client")
public abstract class Client extends AbstractPersistable<Long> {
// ...
}
aplicación A:
@Entity
public class ClientSimple extends Client {
private String name;
// getter, setter
}
aplicación B:
@Entity
public class ClientAdvanced extends Client {
private String description;
// getter, setter
}
Ahora una DAO puede trabajar con los objetos Client
para las aplicaciones A y B, pero la aplicación B puede definir información adicional para su objeto cliente que puede leerse mediante un método de gestión uniqu e para la aplicación B:
aplicación A:
Client client = new ClientSimple();
clientDao.save(client);
la aplicación B:
Client client = new ClientAdvanced();
clientDao.save(client);
Desafortunadamente esto significa que hay una columna DTYPE en cada mesa (o cualquier otro nombre que pudiera elegir) . ¿Hay alguna forma de librarse de esto? No lo necesitamos y está usando el espacio de DB ...
¡Gracias!
EDITAR
Importante tener en cuenta: @MappedSuperclass
no va a funcionar. Estamos usando QueryDSL como nuestra capa de abstracción HQL. Esto requiere clases de tipo de consulta generadas automáticamente para el tipo de consulta de guardado. Sin embargo, estos solo se generarán correctamente si la clase abstracta está anotada con @Entity
.
Ésta es neccessairy porque queremos consulta en la clase abstracta Client
mientras que en verdad consultar ClientSimple
de aplicación A y ClientAdvanced
en la aplicación B:
Así que en cualquier aplicación que esto funcionará:
query.where(QClient.client.name.equals("something");
y en aplicación B que esto funcionará:
query.where(QClientSimple.client.description.equals("something else");
Edit2 - se reducen
Se parece reducirse a esto: ¿Puedo configurar hibernación en el momento del despliegue para establecer el tipo discriminador para una entidad inhertited a un valor fijo. Entonces, yendo con mi ejemplo a Client
siempre será ClientSimple
en una aplicación y ClientAdvanced
en la otra para que no tenga que almacenar esa información en la base de datos?
Como dije: cada aplicación será una instancia de la pila de aplicaciones base. Cada aplicación puede definir columnas adicionales para su base de datos local, pero TODOS los objetos serán del mismo tipo para esa instancia, por lo que le garantizamos que el discriminador es siempre el mismo, lo que lo hace redundante en la base de datos y un caso de uso para la configuración de hibernación.
¿Qué versión de Querydsl estás usando? –
Estamos usando QueryDSL 2.2.3 pero podríamos actualizar si las versiones más recientes admiten superclases mapeadas como objetivos de consulta: así: '@MappedSuperclass @Table public abstract class Client ...' + '@Entity public class ClientSimple extends Client' == > generar tipos de consulta ... ==> consulta: 'QClient.client.name' – Pete
No es compatible directamente, pero puede agregarle un ticket en GitHub. Se implementa fácilmente. –