2010-01-21 17 views
22

Tengo una tabla con un ID generado, pero en algunos casos me gustaría configurarlo solo. ¿Puedo, de alguna manera, forzar a Hibernate a ignorar @GeneratedValue?@Id @GeneratedValue pero establezca su propio valor de ID

+0

¿Lo has probado, mira qué pasa? – skaffman

+5

Sí, a Hibernate no le importa si el ID está configurado o no; de todos modos, se genera un valor. – woezelmann

+2

Sabía que había visto esto antes en alguna parte: http://stackoverflow.com/questions/89439/bypass-generatedvalue-in-hibernate - use 'merge()' en vez de 'persist()' – skaffman

Respuesta

6

Puede ser una exageración pero ¿ha pensado en escribir su propio CustomIDGenerator que probablemente subclases dicen que el AutoGenerator de hibernación y expone un par de métodos donde se puede ajustar el ID de la siguiente clase de objeto que se genere así por ejemplo

class MyGenerator extends .... { 

public void setIdForObject(Class clazz, Long id) { 
    //once you use this API, the next time an object of 
    //type clazz is saved the id is used 
} 

public void setIdForObject(Class clazz, Long id, Matcher matcher) { 
    //once you use this API, the next time an object of 
    //type clazz is saved and the matcher matches yes the id will be 
    //assigned. Your matcher can match properties like name, age etc 
    //to say the matched object 
} 
} 

esto podría complicarse, pero al menos es posible según hibernate doco

+0

En los foros de hibernate.org, hay un usuario que escribió su clase Generator para este escenario exacto: https://forum.hibernate.org/viewtopic.php?p=2404032 – tmarthal

+0

Me lancé sobre esta solicitud en busca de una solución para la misma pregunta (aunque estoy usando EclipseLink en lugar de hibernar). Empecé a usar un generador de ID personalizado pero (al menos en mi caso de EclipseLink) hay un problema: ¿cómo puedo saber si el objeto que necesita persistir ya tiene una identificación o no? No tengo a mano el objeto de entidad en mi generador de ID personalizado. Por lo tanto, no puedo determinar si necesito generar una nueva ID, en caso de que el objeto no tenga una. O si solo devuelvo la identificación que el objeto ya tiene (o tal vez nulo o lo que sea necesario). – Jens

+0

Complemento a mi comentario anterior: En EclipseLink, cuando se crea un generador de secuencias propio, hay un método llamado 'shouldAlwaysOverrideExistingValue' que puede anularse. Esta parece ser una posible solución. Aunque me resulta un poco incómodo anular cosas que no superviso por completo y tampoco encontré documentación adicional a esta [error] (https://bugs.eclipse.org/bugs/show_bug.cgi?id=300556) entrada. – Jens

2

Para su caso de uso, puede agregar manualmente este usuario no. Una forma de hacerlo es colocar la operación de inserción en un archivo llamado "./import.sql" (en su classpath). Hibernate ejecutará estas instrucciones cuando se inicie SessionFactory.

+0

@ Emmanuel Bernard Él dijo: ** pero, en algunos casos, ** me gustaría establecerlo por mi cuenta. Si define cómo Hibernate debe guardar una Entidad (a través del archivo "/.import.sql"), entonces su generación automática de identificador no funcionará, ¿no es así? –

+0

No, no está relacionado, import.sql es SQL simple para que pueda hacer lo que desee, incluida la actualización de la secuencia o la id de la tabla si es necesario. –

+0

Es bueno saber (+1) Lo intentaré. –

4

Aunque esta pregunta se hizo hace ya bastante tiempo, he encontrado la respuesta perfecta para él en this post por @lOranger, y quería compartir eso.

Esta propuesta se comprueba si Identificación actual del objeto se establece en algo distinto de null, y si es así, se utiliza, de lo contrario, se genera utilizando el valor por defecto (o configurado) estrategia de generación.

Es simple, sencillo, y aborda el problema planteado por @Jens, de uno que no puede recuperar el ID actual del objeto.

acabo la pusieran en práctica (mediante la extensión de la UUIDGenerator), y funciona como un encanto: -D

1

crear su propia IdentifierGenerator/SequenceGenerator

public class FilterIdentifierGenerator extends IdentityGenerator implements IdentifierGenerator{ 

@Override 
public Serializable generate(SessionImplementor session, Object object) 
     throws HibernateException { 
    // TODO Auto-generated method stub 
    Serializable id = session.getEntityPersister(null, object) 
      .getClassMetadata().getIdentifier(object, session); 
    return id != null ? id : super.generate(session, object); 
} 

} 

modificar su entidad como:

@Id 
@GeneratedValue(generator="myGenerator") 
@GenericGenerator(name="myGenerator", strategy="package.FilterIdentifierGenerator") 
@Column(unique=true, nullable=false) 
private int id; 
... 

y al guardar en lugar de usar persist() use o update()

Cuestiones relacionadas