Sospendi, inserisci o aggiorna senza selezionare
Domanda
Ho oggetti prodotti che appartengono a determinate categorie, ad esempio la relazione classica tra molti.
@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;
...
}
Voglio inserire e aggiornare i prodotti senza preselezionare le categorie. In questo modo:
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);
È possibile aggiornare e inserire senza selezionare la categoria? Non voglio usare HQL o query dirette per questo.
Soluzione
session.load () esiste specificamente per casi come questo. Quanto segue:
Category category = session.load(categoryId);
product.setCategory(category);
non colpirà il database. Tuttavia, genererà un'eccezione in una fase successiva (durante il flush, più o meno) se non è disponibile una categoria con ID specificato.
L'uso di load ()
è più veloce di merge ()
e non ha effetti collaterali (a cascata, ecc ...)
Altri suggerimenti
Hibernate ha bisogno di un modo sicuro per determinare lo stato del tuo oggetto. Ecco perché sta facendo molta strada per assicurarsi che non sia possibile mescolare oggetti di sessioni diverse (quindi non è possibile caricare le categorie all'avvio e utilizzarle in seguito).
La soluzione è caricare le categorie all'avvio, impostare un provider di memorizzazione nella cache come ehcache
per questa classe e quindi utilizzare questo codice:
Product product = new Product(somename);
product.setCategory(session.merge(category));
Ciò non causerà alcun round trip DB se si configura la cache che le istanze di categoria non possono cambiare.
Ho appena provato a seguire:
Category category = new Category(categoryId);
product.setCategory(category);
E ha funzionato, intendo dire che il record del prodotto in db ha ottenuto il collegamento corretto alla categoria e alla categoria con ID
categoryId
non sono cambiati.