0

I am trying to do a simple example using java.util.Map in Hibernate by creating a Customer entity with a Map of Order entities.

Here are my Java classes:

Customer.java:

@Entity
public class Customer {
    @Id
    @GeneratedValue
    private Integer id;

    @OneToMany(mappedBy = "customer")
    @MapKey(name = "orderNumber")
    private Map<String, Order> orders = new  HashMap<String, Order>();;
}

Order.java

@Entity
@Table(name="TB_ORDER")
public class Order {
    @Id
    @GeneratedValue
    private Integer id;

    private String orderNumber;

    @ManyToOne
    private Customer customer;
}

Now I have created a program to save a customer and Orders:

public class AppTest {
    public static void main(String[] args) {
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        saveCustomer(session);
        HibernateUtil.getSessionFactory().close();
    }

    private static void saveCustomer(Session session) {
        session.getTransaction().begin();
        Customer customer = new Customer();
        Order order = new Order();
        order.setCustomer(customer);
        //order.setOrderNumber("100");
        Map<String, Order> map = new HashMap();
        map.put("100", order);
        customer.setOrders(map);
        session.save(customer);
        session.save(order);
        session.getTransaction().commit();
    }
}

As per my mapping, the key of Map represents the orderNumber property of my Order class. So when I created a map with key as "100" and trying save using Hibernate then the field is set as empty in my database for TB_ORDER table. But if I try to use order.setOrderNumber("100") then the value is getting saved to database. Please tell me where I am doing mistake?

Neil Stockton
  • 11,383
  • 3
  • 34
  • 29
Chaitanya
  • 15,403
  • 35
  • 96
  • 137

1 Answers1

2

You're not doing any mistake. It's your responsibility to maintain the coherence of the object graph in memory. What is mapped to the column in the database is the orderNumber field of the Order entity. So if it's null, Hibernate saves null in the column.

The MapKey annotation tells Hibernate how to extract the key from the entity when it loads a Customer's orders from the database and populates the map. That's all.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • Thanks for Clarifying JB. So does it mean the key of my HashMap is never used by Hibernate/JPA while saving the entities, so I can just put null for my key? Also is there any way to tell Hibernate to persist my key also without setting property of my Order entity? – Chaitanya Aug 21 '14 at 05:34
  • 1
    No, it isn't. BTW, the map is the inverse side of the association, so what matters to Hibernate is the order's customer field to know if the association exists. The orderNumber column is mapped to the orderNumber field, and that is thus where Hibernate gets the value for this column. Why would you put null for your key though? That doesn't make sense. A map can only have one null key, and you want your object graph to be correct, don't you? Regarding your last question, AFAIK, no. – JB Nizet Aug 21 '14 at 05:56
  • Can you please explain what it means that `map is the inverse side of the association`, as I am still learning hibernate, I am not able to understand this statement. – Chaitanya Aug 21 '14 at 06:29
  • 1
    Read http://stackoverflow.com/questions/10968536/jpa-difference-in-the-use-of-the-mappedby-property-to-define-the-owning-entity and http://stackoverflow.com/questions/12552714/many-to-many-hibernate-inverse-side-ignored – JB Nizet Aug 21 '14 at 06:35