views:

23

answers:

2

Suppose I have a class 'Cheese' with fields type and purchaseDate, such that:

public class Cheese{
    CheeseType cheeseType;
    String purchaseDate;

    public setPurchaseDate(String value){
      purchaseDate=value;
      }

public Class CheeseType{
      String type;

      public setType(String value){
         type=value;
         }

public class MyClass{
     Cheese cheese = new Cheese();
     cheese.setType("cedar");
     cheese.setPurchaseDate("01/02/03");
     // Code to get entity manager etc
     em.getTransaction().begin();
     em.persist(cheese);
     em.getTransaction().commit();
     // Code to close entity manager etc
     }

Please ignore any silly mistakes in the code, I've tried to simplify my problem!

Obviously there will be many other parameters in a real world situation, but in this case: the same purchaseDate can exist many times int he database (as many times as I buy cheese!) but the 'type' already exists in the database (from previous purchases let's say). Now, each time I persist an instance of 'Cheese' to the database, a new 'CheeseType' is added, i.e. there are multiple 'cedars'. How would I go about getting each instance of 'Cheese' to check what CheeseTypes already exists and not create multiple new cedars in the database? I think I need to merge somewhere, but the examples I have seen don't seem to be the same type of thing that I'm trying to do.

If anyone has any tips, I would greatly appreciate hearing them! Apologies if I've made any rookie mistakes here!

A: 

If cheese type is stored in its own table, you should have a mapping for it. Similarly you should have a mapping for Cheese too, where you define how to map its properties. There you can specify the association between Cheese and CheeseType.

For this to work, CheeseType needs an identifier, which uniquely identifies its instances. This allows you to know that two CheeseType objects both having type = "cheddar" are indeed the same logical instance. An obvious possibility is the type field, however it is usually better to use a generated internal ID for this purpose.

For further details, see the chapter Mapping associations in the Hibernate Reference.

Péter Török
A: 

How would I go about getting each instance of 'Cheese' to check what CheeseType already exists and not create multiple new cedars in the database?

I don't know if this will suit your needs but if you know that you already have a "cedar" CheeckType (assuming CheeseType is an entity and "cedar" is the identifier - your example isn't clear/coherent), then you could use Session#load(), or EntityManager#getReference() if you are using JPA, to set the association when creating a new Cheese, like this:

 em.getTransaction().begin();

 CheeseType type = em.getReference(CheeseType.class, "cedar"); // no db hit 

 Cheese cheese = new Cheese();
 cheese.setType(type);
 cheese.setPurchaseDate("01/02/03");

 em.persist(cheese);
 em.getTransaction().commit();

If you don't know if you already have a "cedar" CheeseType, then you could try a merge indeed. Here is what the JPA spec, section 3.2.4.1 writes about it:

The semantics of the merge operation applied to an entity X are as follows: If X is a new entity instance, a new managed entity instance X1 is created and the state of X is copied into the new managed entity instance X1.

So merge will insert/update depending on the state of the entity. But make sure to really understand how merge works (see links below), merging is not an obvious concept IMO.

Resources

Related questions

Pascal Thivent