Engineering Full Stack Apps with Java and JavaScript
There might be situations where you would want to modify the attributes of the embedded class (eg. Address) within an embedding class (eg. User), for instance, changing the database column name for a field. You can do this within the embedded class itself. But what if you don’t have access to the embedded class or if you want different behavior for two different instances of the embedded class; you will have to override the embedded class behavior in the embedding class. We can use @AttributeOverride annotation to override the details of a field of the embedded class and then enclose all such @AttributeOverride annotations inside @AttributeOverrides annotation.
Example: If you are not following the tutorials in order, refer to the article http://javajee.com/your-first-hibernate-program-using-hibernate-43 for the basic setup including hibernate configuration file. This example is a continuation of http://javajee.com/embedding-value-types-within-an-entity-class-in-hibernate-43 and we will be modifying the classes in that example to demonstrate @AttributeOverrides and @AttributeOverride.
First modify the User class as below:
package com.javajee.hiberex.dto;
import javax.persistence.AttributeOverrides;
import javax.persistence.AttributeOverride;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Column;
@Entity
public class User {
@Id
int id;
private String name;
@Embedded
@AttributeOverrides({
@AttributeOverride(
name="houseno",
column=@Column(name="HS_1")
),
@AttributeOverride(
name="street",
column=@Column(name="STR_1")
)
})
private Address address1;
@Embedded
@AttributeOverrides({
@AttributeOverride(
name="houseno",
column=@Column(name="HS_2")
),
@AttributeOverride(
name="street",
column=@Column(name="STR_2")
)
})
private Address address2;
public Address getAddress1() {
return address1;
}
public void setAddress1(Address address1) {
this.address1 = address1;
}
public Address getAddress2() {
return address2;
}
public void setAddress2(Address address2) {
this.address2 = address2;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
To test this we will also modify the user test class as below:
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import com.javajee.hiberex.dto.Address;
import com.javajee.hiberex.dto.User;
public class UserTest {
public static void main(String[] args) {
User u = new User();
u.setId(1);
u.setName("Heartin");
Address addr = new Address();
addr.setHouseno(777);
addr.setStreet("MyStreet");
u.setAddress1(addr);
u.setAddress2(addr);
Configuration configuration = new Configuration();
configuration.configure();
serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(u);
session.getTransaction().commit();
//Code to get data is same as before, but to test this change, it is not needed.
}
}
Now execute the class UserTest and you can see the below insert query in the console (if you have set sql_show as true):
Hibernate: insert into User (HS_1, STR_1, HS_2, STR_2, name, id) values (?, ?, ?, ?, ?, ?)