2009-11-30 12 views
10

Tengo un producto de objetos que pertenece a ciertas categorías, es decir, la relación clásica de muchos a uno.Hibernar, insertar o actualizar sin seleccionar

@Entity 
public class Product{ 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    Long id; 

    String name; 
    Double price; 
    @ManyToOne(fetch = FetchType.LAZY) 
    Category category; 
... 
} 

@Entity 
public class Category implements Identifiable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    private String name; 
... 
} 

Quiero insertar y actualizar productos sin preseleccionar categorías. De esta manera:

Product product = dao.get(productId); 
Category category = dao.get(categoryId); 
product.setCategory(category); 
dao.update(product); 

o

Product product = new Product(somename); 
Category category = dao.get(categoryId); 
product.setCategory(category); 
dao.insert(product); 

¿Es posible actualizar e insertar sin categoría de selección? No quiero usar HQL o consultas directas para eso.

Respuesta

10

session.load() existe específicamente para casos como este. Lo siguiente:

Category category = session.load(categoryId); 
product.setCategory(category); 

no golpeará la base de datos. Sin embargo, arrojará una excepción en una etapa posterior (durante el enjuague, más o menos) si no hay una categoría disponible con una identificación dada.

Usando load() es más rápido que merge() y no tiene efectos secundarios (en cascada, etc ...)

2

Hibernate necesita una forma segura de determinar el estado de su objeto. Es por eso que es un gran avance asegurarse de que no se pueden mezclar objetos de diferentes sesiones (por lo que no se pueden cargar las categorías al inicio y luego usarlas más adelante).

La solución es cargar las categorías en el arranque, establecer un proveedor de almacenamiento en caché como ehcache para esta clase y luego usar este código:

Product product = new Product(somename); 
product.setCategory(session.merge(category)); 

que no cause ningún DB de ida y vuelta si configura el caché que las instancias de categoría no pueden cambiar.

0

acabo intentado siguiente:

Category category = new Category(categoryId); 
product.setCategory(category); 

y funcionó, me refiero registro del producto en db obtuvo el enlace correcto a la categoría y categoría con id

categoryId 

no ha cambiado.

+1

El problema con este enfoque es que está creando una nueva instancia de entidad persistente con el mismo identificador. Puede haber funcionado para usted esta vez porque 'Category' en cuestión no estaba asociado con la sesión ** actual **; si lo fuera, Hibernate lanzaría una excepción. También es peligroso en términos de integridad de datos; si tuviera que especificar la cascada de su categoría de muchos a uno en 'category', el código anterior sobrescribiría su categoría original con todos los valores en blanco (o fallaría con un error de violación de restricciones) – ChssPly76

+0

Hm, tenía la sensación de estarlo algo desagradable aquí. Gracias por la aclaración. – Vladimir

Cuestiones relacionadas