MODEL : Create Hibernate ORM Models
We will create five model classes mapping to our database tables, please download here:
Java Class Files | Table Name |
Address.java | ADDRESS |
Customer.java | CUSTOMER |
Orders.java | ORDERS |
Product.java | PRODUCT |
Shop.java | SHOP |
Nil
We don’t need to create a model class for this table. But, we will use @ManyToMany annotation in Orders.java to state this join table |
ORDER_PRODUCT |
One-To-One Relationship:
Shop.java and Address.java are one-to-one relationship, we are using @OneToOne in Shop.java to state this relationship as:
@OneToOne(fetch = FetchType.EAGER, cascade = {CascadeType.REMOVE})
@JoinColumn(name=”ADDRESS_ID”)
private Address address;
And you can also define this relationship in Address.java as bidirectional like:
@OneToOne
@PrimaryKeyJoinColumn
private Shop shop;
There are two fetching type: eager and lazy.
FetchType.EAGER | The joined table will be fetched eagerly.
It will load the join table as soon as the table is initially fetched. For example, the join table “address” will be loaded when “shop” table is initially fetched.
So, Hibernate will create an JOIN query to get both tables.
Under Orders.java, you can find: @NotNull @ManyToOne(optional = false, fetch = FetchType.EAGER) @JoinColumn(name = “CUSTOMER_ID”)
|
FetchType.LAZY | The joined table will be fetched lazily.
It will not load the join table when the table is initially fetched. But, join table will be loaded when using Hibernate.initialize() within Transactional to initialize lazy tables.
For example, under Orders.java, you can find:
@ManyToMany( fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE } ) @JoinTable(name = “ORDER_PRODUCT”, joinColumns = { @JoinColumn(name = “ORDER_ID”) }, inverseJoinColumns = { @JoinColumn(name = “PRODUCT_ID”) }) private Set<Product> products = new HashSet<Product>();
It means that Hibernate will not load “product” table when “orders” table is initialized. If you need to use “product” table, you need to call (in OrdersDaoImpl.java) in order to fetch “product” table:
Hibernate.initialize(orders.getProducts());
Please note that Hibernate.initialize() can be called within Transactional. So, you need to have @Transactional in OrdersDaoImpl.java or OrdersDaoImpl.java
|
When do you need EAGER?
If you always need to show both joined tables in your application, it is suggested to use EAGER.
When do you need LAZY?
If you seldom need to show both joined tables in your application, it is suggested to use LAZY.
One-To-Many Relationship:
Customer.java and Orders.java are one-to-many relationship, we are using @OneToMany in Customer.java to state this relationship as:
@OneToMany(mappedBy = “customer”, fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
private List<Orders> orders;
Same as @OneToOne, this relationship can be bidirectional. So, you can state bidirectional @OneToMany in Orders.java like:
@NotNull
@ManyToOne(optional = false, fetch = FetchType.EAGER)
@JoinColumn(name = “CUSTOMER_ID”)
private Customer customer;
Many-To-Many Relationship:
Orders.java and Product.java are many-to-many relationship, you can find @ManyToMany in Orders.java to state this relationship as:
@ManyToMany( fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE } )
@JoinTable(name = “ORDER_PRODUCT”,
joinColumns = { @JoinColumn(name = “ORDER_ID”) },
inverseJoinColumns = { @JoinColumn(name = “PRODUCT_ID”) })
private Set<Product> products = new HashSet<Product>();
Same as @OneToOne and @OneToMany, this relationship can be bidirectional. So, you can state bidirectional @ManyToMany in Product.java as:
@ManyToMany( fetch = FetchType.LAZY, mappedBy = “products”, cascade = CascadeType.ALL )
private Set<Orders> orders = new HashSet<Orders>();
Remember that you don’t need to create the model Java class for the mapping table “ORDER_PRODUCT”, because @ManyToMany will help to manage the data records for this mapping table.