@AttributeOverride annotation
Used to override the mapping of a Basic (whether explicit or default) property or field or Id property or field.
May be applied to an entity that extends a mapped superclass or to an embedded field or property to override a basic mapping or id mapping defined by the mapped superclass or embeddable class (or embeddable class of one of its attributes).
May be applied to an element collection containing instances of an embeddable class or to a map
collection whose key and/or value is an embeddable class. When AttributeOverride
is
applied to a map, "key." or "value." must be used to prefix the name of the
attribute that is being overridden in order to specify it as part of the map key or map value.
To override mappings at multiple levels of embedding, a dot (".") notation form must be used in
the name element to indicate an attribute within an embedded attribute. The value of each
identifier used with the dot notation is the name of the respective embedded field or property.
If AttributeOverride
is not specified, the column is mapped the same as in the
original mapping.
@AttributeOverrides annotation
Used to override mappings of multiple properties or fields.
Understand using example
We strongly recommend to read these article before moving ahead, component mapping in hibernate using JPA annotation, this post, and how mapping of column happens when mapping file and @Column annotation is not used..
If we want to change the column names of component address to something like "address_street", "address_city", and "address_zipcode" as table below.
We can do the same by using the name attribute of @Column
annotation.
package com.walking.techie.entity; import javax.persistence.Column; import javax.persistence.Embeddable; @Embeddable public class Address { @Column(name = "address_street") private String street; @Column(name = "address_city") private String city; @Column(name = "address_zipcode") private String zipcode; public Address() { } public Address(String street, String city, String zipcode) { this.street = street; this.city = city; this.zipcode = zipcode; } }
But sometimes, We need to override the settings of component class into the particular entity class. For example, Here by default attributes of address component class will be mapped to street, city, and zipcode columns. But, if you wanted to map these columns with some other name for this "Person" entity. You can do it using @AttributeOverride annotation.
package com.walking.techie.entity; import javax.persistence.AttributeOverride; import javax.persistence.AttributeOverrides; import javax.persistence.Column; import javax.persistence.Embedded; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import lombok.Getter; import lombok.Setter; @Entity @Table(name = "Person") @Getter @Setter public class Person { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private Long id; @Column(name = "name", nullable = false) private String name; @Embedded @AttributeOverrides({ @AttributeOverride(name = "street", column = @Column(name = "address_street")), @AttributeOverride(name = "city", column = @Column(name = "address_city")), @AttributeOverride(name = "zipcode", column = @Column(name = "address_zipcode")) }) private Address address; public Person() { } public Person(String name, Address address) { this.name = name; this.address = address; } }
In "Person" entity, street attribute mapped to "address_street" column, city attribute mapped to "address_city" column, and zipcode attribute mapped to "address_zipcode" column.
package com.walking.techie.entity; import javax.persistence.Embeddable; @Embeddable public class Address { private String street; private String city; private String zipcode; public Address() { } public Address(String street, String city, String zipcode) { this.street = street; this.city = city; this.zipcode = zipcode; } }
When requirement comes like "Person" entity should have two address say "homeAddress" and "billingAddress". We can achieve the same using the @AttributeOverride annotation. The "Address" class is embeddable as above. So it is a value type.
The "Person" entity will be like below.
package com.walking.techie.entity; import javax.persistence.AttributeOverride; import javax.persistence.AttributeOverrides; import javax.persistence.Column; import javax.persistence.Embedded; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import lombok.Getter; import lombok.Setter; @Entity @Table(name = "Person") @Getter @Setter public class Person { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private Long id; @Column(name = "name", nullable = false) private String name; @Embedded @AttributeOverrides({ @AttributeOverride(name = "street", column = @Column(name = "home_street")), @AttributeOverride(name = "city", column = @Column(name = "home_city")), @AttributeOverride(name = "zipcode", column = @Column(name = "home_zipcode")) }) private Address homeAddress; @Embedded @AttributeOverrides({ @AttributeOverride(name = "street", column = @Column(name = "billing_street")), @AttributeOverride(name = "city", column = @Column(name = "billing_city")), @AttributeOverride(name = "zipcode", column = @Column(name = "billing_zipcode")) }) private Address billingAddress; public Person() { } public Person(String name, Address homeAddress, Address billingAddress) { this.name = name; this.homeAddress = homeAddress; this.billingAddress = billingAddress; } }
AttributeOverrideClient
package com.walking.techie; import com.walking.techie.entity.Address; import com.walking.techie.entity.Person; import com.walking.techie.utils.HibernateUtil; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; public class AttributeOverrideClient { public static void main(String[] args) { // get session factory of an application SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); // Open a session Session session = sessionFactory.openSession(); Transaction transaction = null; try { // Begin a unit of work and return the associated Transaction object. transaction = session.beginTransaction(); Address homeAddress = new Address("6th cross, 6th main", "Bangalore", "560078"); Address billingAddress = new Address("11th cross, 7th main", "New Delhi", "110005"); Person person = new Person("Santosh", homeAddress, billingAddress); session.persist(person); // commit the transaction transaction.commit(); } catch (Exception e) { if (transaction != null) { transaction.rollback(); e.printStackTrace(); } } finally { if (session != null) { // End the session by releasing the JDBC connection and cleaning up. session.close(); } } } }
After running the code. The data in "Person" table will be like below.
Please find the working code from git.
Helpful
ReplyDelete