Hibernate – Llaves extranjeras en lugar de entidades

Actualmente, Hibernate me permite cargar objetos definidos por relaciones * a uno directamente con

entity1.getEntity2() 

¿Es posible obtener la clave externa en lugar del objeto?

El enfoque actual que veo es agregarme a mi mapeo:

 @JoinColumn(name="message_key") @ManyToOne(targetEntity=Message.class,fetch=FetchType.LAZY) private Message message; //these lines currently exist @Column(name="message_key") private Long message_fk; //the idea is to add those 2 lines 

¿Hay un mejor enfoque para obtener la clave externa, o es este el único?

Si tu puedes hacerlo. Solo tiene que dejar en claro para hibernación cuál es el mapeo que se supone que debe mantener, así:

 @Column(name="message_key", updatable=false, insertable=false) private Long message_fk; 

Si aún desea una referencia a su entidad pero no desea cargarla desde la base de datos solo para obtener la clave externa, su enfoque es el correcto. Agregue insertable y updatabale = false al atributo Columna para evitar perder la referencia correcta a una entidad.

 @JoinColumn(name = "message_key") @ManyToOne(targetEntity = Messages.class, fetch = FetchType.LAZY) private Messages message; @Column(name = "message_key", insertable = false, updatable = false) private Long message_fk; 

En realidad, es un comportamiento predeterminado de Hibernate cargar solo la clave externa en lugar del objeto de mensaje si FetchType es LAZY. Es por eso que hay proxies para los objetos que se cargarán cuando especifique LAZY FetchType.

La clave externa no es visible directamente, pero es, por supuesto, la clave del objeto en el extremo “uno” de la relación OneToMany.

Sin embargo, con un tipo de acceso basado en el campo (por ejemplo, en su caso, donde las anotaciones se colocan en los campos), hay un problema de hibernación sin resolver: Hibernate carga todo el objeto detrás del proxy de la base de datos. ( http://blog.xebia.com/2009/06/13/jpa-implementation-patterns-field-access-vs-property-access/ )

Mi sugerencia concreta sería (como, por ejemplo, la respuesta “correcta” no funcionó en mi caso):

  • Utilice el objeto de mensaje directamente, ya que Hibernate solo lo cargará si se necesitan datos que no sean de clave extranjera. No especifique un campo adicional para la clave externa.
  • Cambie la clase para usar el acceso a la propiedad, es decir, defina getters y setters, y coloque sus anotaciones de los campos a los getters.
 Long fk = entity1.getEntity2().getId(); 

Esto debería funcionar. No funcionaría si tiene claves primarias compuestas referenciadas como claves externas, pero su solución tampoco funcionaría en ese caso. Considerando mi solución, incluso una clave compuesta no se vería tan fea.

 Long fkField1 = entity1.getEntity2().getCol1(); String fkField2 = entity1.getEntity2().getCol2(); 

Algo así funcionará.

EDITAR: Pensando más en su solución propuesta, no funcionaría de todos modos porque Hibernate ya intenta crear automáticamente un campo FK para una relación asignada, por lo que la definición de otra @Column simplemente intentaría enlazar a una segunda columna con el mismo nombre.