Nueva entidad con ID preestablecido detectado como "entidad separada"

Tengo una entidad Player con esta definición de identificación

@Id
@GeneratedValue
@Column(updatable=false)
private long id;

Sin embargo, a veces (pero no siempre) quiero crear una nueva instancia con una ID preestablecida.

player = new Player(...);
player.setId(externalId);
em.persist(player);

Aparentemente, esto hace que Hibernate lo vea como una entidad separada, lanzando la excepción

org.hibernate.PersistentObjectException: entidad separada pasada a persistir

¿Cómo puedo evitar esto?

preguntado el 03 de mayo de 12 a las 10:05

2 Respuestas

podría quitar el @GeneratedValue y generar IDs yo mismo, algo como:

begin transaction
if id not preset {
    do {
        id = random number
    } while (id in use)
}
create player with id
commit transaction

Eso debería ser seguro, con la transacción, pero es menos óptimo que dejar que la base de datos se ocupe de ello.

contestado el 03 de mayo de 12 a las 10:05

o cambie el "largo" a Largo. Esto permite nulos (es decir, no configurados) - Núcleo de datos

Hay algo mal allí. ¿Podría decirnos por qué quiere una identificación fija? Porque en realidad estás diciendo "por favor, crea una ID para mí, yo NUNCA quiere lidiar con esto", entonces a veces está tratando de establecer una identificación usted mismo, lo que probablemente significa que está corrompiendo todo.

Esa excepción podría deberse a que está configurando una ID que ya se usa. Luego, cuando intenta persistir, hibernate lo detecta como no sincronizado (separado) con lo que está en la base de datos, por lo que simplemente lanza esa excepción.

contestado el 03 de mayo de 12 a las 10:05

Estoy ejecutando el mismo software de servidor dos veces. En un caso, las identificaciones se generan automáticamente, pero en otro se proporcionan externamente (por Facebook, en este caso). Por cierto, la base de datos está vacía, por lo que no puede ser que la identificación ya esté en uso. - Bart van Heukelom

Ok, entonces está vacío y está configurando una ID que está marcada como "generada automáticamente", lo que significa que cuando le pida a su em que persista, mirará la ID, si es nula (no configurada) generará una nueva y persiste tu entidad. Si no es nulo, buscará en la base de datos para encontrar la entidad correspondiente y actualizar (Creo que ha pasado mucho tiempo sin Java para mí: P). Entonces, cuando configura su ID, busca una entidad que no existe y le dice que su entidad no está sincronizada. (Supongo que asume que su entidad ha sido eliminada entre su supuesto "buscar ()" y "persistir ()" o algo así) - Michael de Keyser

Errm, ¿cómo puede un "largo" ser "desarmado" (nulo)? no puede siempre tiene un valor, ya sea aplicado por el compilador o por el usuario. - Núcleo de datos

Posiblemente 0 se vea como no configurado cuando se trata de identificaciones generadas automáticamente. - Bart van Heukelom

Estoy respondiendo aquí porque supongo que no tengo suficiente representante para comentar otras respuestas: podría usar algún tipo de identificación de "su lado" que no significaría nada para DB pero eso significaría todo para usted y luego establecer algún algoritmo de generación para que puedas hacer lo que quieras con él. Apuesto a que hay muy buenos algoritmos de generación de ID por ahí. Editar: este comentario no tiene sentido, eso es realmente lo que quieres hacer. Y creo que este es el camino correcto a seguir. - Michael de Keyser

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.