2012-10-04 35 views
17

Esto debe ser bastante ingenuo, pero tengo una duda sobre cuándo usar @Entity y @Embeddable.@embeddable vs @entity para mapear una colección

Supongo que tengo una clase User y Notification.

@Entity 
public class User{ 
    //other properties 
    @onetomany 
    private List<Notification> notifications; 
} 

@Entity 
public class Notification{ 
    //properties 
} 

entiendo que habrá mesas para la clase User y Notification, y una tercera tabla de mapeo. ¿Qué pasa si lo hago así?

@Entity 
public class User { 
    //other properties 
    @ElementCollection 
    private List<Notification> notifications; 
} 

@Embeddable 
public class Notification{ 
    //properties 
} 

Sé que esto no creará una tabla para Notification. Pero aún puedo almacenar mis objetos de notificación. Fui a través de la documentation, pero par de dudas:

  1. ¿Se basa en si quiero ver la clase B como una tabla separada?
  2. ¿Existe una diferencia de rendimiento b/w al crear una tabla y un objeto incrustable?
  3. ¿Qué no puedo hacer con el objeto incrustable que puedo hacer con una tabla que no sea consultar directamente la tabla?

NOTAS

Para cualquiera que lea esta pregunta, este question también podrían ayudarte.

Respuesta

8
  1. ¿Se basa en si deseo ver la clase B como una tabla separada?

Sí, cuando se utiliza @Embedded, que incrusta @Embeddable entidad en @Entity clase, lo que hace que sea para añadir columnas de entidad integrada en una misma mesa de @Entity clase.

  1. ¿Hay una diferencia de rendimiento b/w creando una tabla y un objeto incrustable?

Cuando utiliza @Embedded, para la creación de la tabla, se requiere una consulta, también para insertar y seleccionar una fila. Pero si no lo usa, se requieren varias consultas, por lo tanto, el uso de @Embedded produce un mayor rendimiento, podemos decir.

  1. ¿Qué puedo hacer con el objeto incrustable que puedo hacer con una tabla que no sea consultar directamente la tabla?

La eliminación de la entidad incrustada respectiva puede ser, pero puede haber infracciones de constricción de integridad para esto.

+0

Supongo que puedo usar Embeddable con ElementCollection. No necesito usar @Embedded rt? – shazinltc

+0

No obtuve su tercer punto. – shazinltc

+0

3er punto: considere que la persona contiene la dirección (incrustada), si hay una tabla separada para ambos, puede eliminar directamente la dirección asociada, pero si la tabla de la persona tiene F.K. abordar, puede causar una violación de la restricción de integridad. – deepakraut

0

En JPA, hay varias maneras de crear campos de clave compuesta. Veamos el método usando @Embeddable annotation.
Comencemos con la clase Entity.

@Entity 
@Table 
public class TraceRecord { 
    @Id 
    private TraceRecordPk id; 

    @Version 
    @Transient 
    private int version; 

    @Column(columnDefinition = "char") 
    private String durationOfCall; 

    @Column(columnDefinition = "char") 
    private String digitsDialed; 

    @Column(columnDefinition = "char") 
    private String prefixCalled; 

    @Column(columnDefinition = "char") 
    private String areaCodeCalled; 

    @Column(columnDefinition = "char") 
    private String numberCalled; 
} 

Esta es una clase de entidad bastante simple con un @Id y @Version campo y algunas definiciones @column. Sin entrar en demasiados detalles, verá que el campo @Version también tiene la anotación @Transient. Lo hice simplemente porque mi tabla tampoco tiene una columna para rastrear versiones, pero mi base de datos está registrada por diario, por lo que no estoy demasiado preocupado por el control de versiones. También notará que los campos @Column tienen un valor de "char" establecido en el atributo columnDefinition. Esto se debe a que los campos en mi tabla se definen como char y no como varchar. Si fueran varchar, no necesitaría hacer esto porque un String se asigna a un campo varchar de manera predeterminada. El campo @Id es lo que me interesa ahora. No es un tipo estándar de Java, sino una clase que he definido a mí mismo. Aquí está esa clase.

@Embeddable 
public class TraceRecordPk implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Temporal(TemporalType.DATE) 
    @Column 
    private Date dateOfCall; 

    @Column(columnDefinition="char") 
    private String timeOfCall; 

    @Column(columnDefinition="char") 
    private String callingParty; 

    /** 
    * Constructor that takes values for all 3 members. 
    * 
    * @param dateOfCall Date the call was made 
    * @param timeOfCall Time the call was made 
    * @param callingParty Extension from which the call originated 
    */ 
    public TraceRecordPk(Date dateOfCall, String timeOfCall, String callingParty) { 
     this.dateOfCall = dateOfCall; 
     this.timeOfCall = timeOfCall; 
     this.callingParty = callingParty; 
    } 
} 

Para hacer esta clase capaz de ser un campo @Id en una clase de entidad, que tiene que ser anotado con @Embeddable como he mencionado anteriormente. Los 3 campos que he seleccionado para mi clave compuesta son simplemente definiciones @Column normales. En lugar de crear getters/setters para cada campo, simplemente he implementado un constructor que toma valores para los 3 campos, haciendo que cualquier instancia sea inmutable. Al anotar una clase con @Embeddable, esa clase tendrá que implementar Serializable. Así que he agregado un serialVersionUID predeterminado para acomodar.

Ahora que tiene una clase creada y anotada con @Embeddable, ahora puede usarla como el tipo para un campo @Id en su clase Entity. Cosas simples eh.

+0

Gracias pero he leído este [artículo] (http://jpgmr.wordpress.com/2011/03/27/using-the-jpa-embeddable-annotation-to-create-your-own-composite-keys /). No responde mi pregunta. Mi pregunta no está relacionada de todas formas con las claves compuestas. – shazinltc

Cuestiones relacionadas