In earlier post we had OneToMany
uni-directional mapping with the help of JoinTable
. In this post we will see how can we make it unidirectional without using JoinTable
.
Let’s create our eclipse project and then add update our pom.xml
.
pom.xml
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > <modelVersion>4.0.0</modelVersion> <groupId>com.mumz.test.hibernatesearch</groupId> <artifactId>MumzHibernateSearch</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>MumzHibernateSearch</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.hibernate.javax.persistence</groupId> <artifactId>hibernate-jpa-2.0-api</artifactId> <version>1.0.1.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>4.1.7.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>4.1.7.Final</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.21</version> </dependency> </dependencies> </project>
Next we will write our Entity to model Book
and BookShelf
tables. BookShelf
will contain a set of books. First we will write our MHSBookEntityBean
.
MHSBookEntityBean.java
package com.mumz.test.hibernatesearch.entitybeans; import java.io.Serializable; import java.lang.Long; import java.lang.String; import javax.persistence.*; /** * The Class MHSBookEntityBean. * @author prabhat.jha */ @Entity @Table(name = "BOOK") public class MHSBookEntityBean implements Serializable { /** The Constant serialVersionUID. */ private static final long serialVersionUID = -5129783468137830152L; /** The id. */ private Long id = null; /** The name. */ private String name = null; /** The author. */ private String author = null; /** * Instantiates a new mHS book entity bean. */ public MHSBookEntityBean() { super(); } /** * Gets the id. * * @return the id */ @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "BOOK_ID") public Long getId() { return this.id; } /** * Sets the id. * * @param id * the new id */ public void setId(Long id) { this.id = id; } /** * Gets the name. * * @return the name */ @Column(name = "BOOK_NAME") public String getName() { return this.name; } /** * Sets the name. * * @param name * the new name */ public void setName(String name) { this.name = name; } /** * Gets the author. * * @return the author */ @Column(name = "BOOK_AUTHOR") public String getAuthor() { return author; } /** * Sets the author. * * @param author * the new author */ public void setAuthor(String author) { this.author = author; } /** (non-Javadoc) * @see java.lang.Object#hashCode() */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((author == null) ? 0 : author.hashCode()); result = prime * result + ((id == null) ? 0 : id.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } /** (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (!(obj instanceof MHSBookEntityBean)) { return false; } MHSBookEntityBean other = (MHSBookEntityBean) obj; if (author == null) { if (other.author != null) { return false; } } else if (!author.equals(other.author)) { return false; } if (id == null) { if (other.id != null) { return false; } } else if (!id.equals(other.id)) { return false; } if (name == null) { if (other.name != null) { return false; } } else if (!name.equals(other.name)) { return false; } return true; } /** (non-Javadoc) * @see java.lang.Object#toString() */ @Override public String toString() { return "MHSBookEntityBean [id=" + id + ", name=" + name + ", author=" + author + "]"; } }
Next we will write our MHSBookShelfEntityBean
MHSBookShelfEntityBean.java
package com.mumz.test.hibernatesearch.entitybeans; import java.io.Serializable; import java.lang.Long; import java.lang.String; import java.util.HashSet; import java.util.Set; import javax.persistence.*; /** * The Class MHSBookShelfEntityBean. * * @author prabhat.jha */ @Entity @Table(name = "BOOK_SHELF") public class MHSBookShelfEntityBean implements Serializable { /** The Constant serialVersionUID. */ private static final long serialVersionUID = -7127365575633206221L; /** The id. */ private Long id; /** The name. */ private String name; /** The books. */ private Set<MHSBookEntityBean> books = new HashSet<MHSBookEntityBean>(); /** * Instantiates a new mHS book shelf entity bean. */ public MHSBookShelfEntityBean() { super(); } /** * Gets the id. * * @return the id */ @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "BOOK_SHELF_ID") public Long getId() { return this.id; } /** * Sets the id. * * @param id * the new id */ public void setId(Long id) { this.id = id; } /** * Gets the name. * * @return the name */ @Column(name = "BOOK_SHELF_NAME") public String getName() { return this.name; } /** * Sets the name. * * @param name * the new name */ public void setName(String name) { this.name = name; } /** * Gets the books. * * @return the books */ @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) @JoinColumn(name = "BOOK_SHELF_ID", referencedColumnName = "BOOK_SHELF_ID") public Set<MHSBookEntityBean> getBooks() { return books; } /** * Sets the books. * * @param books * the new books */ public void setBooks(Set<MHSBookEntityBean> books) { this.books = books; } /** * (non-Javadoc) * * @see java.lang.Object#hashCode() */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((books == null) ? 0 : books.hashCode()); result = prime * result + ((id == null) ? 0 : id.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } /** * (non-Javadoc) * * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (!(obj instanceof MHSBookShelfEntityBean)) { return false; } MHSBookShelfEntityBean other = (MHSBookShelfEntityBean) obj; if (books == null) { if (other.books != null) { return false; } } else if (!books.equals(other.books)) { return false; } if (id == null) { if (other.id != null) { return false; } } else if (!id.equals(other.id)) { return false; } if (name == null) { if (other.name != null) { return false; } } else if (!name.equals(other.name)) { return false; } return true; } /** * (non-Javadoc) * * @see java.lang.Object#toString() */ @Override public String toString() { return "MHSBookShelfEntityBean [id=" + id + ", name=" + name + ", books=" + books + "]"; } }
Highlighted code above shows removal of JoinTable (name is the name of the column in BOOK table and referencedColumnName is the name of column in BOOK_SHELF table).
Finally our persistence.xml and some test code to check our model.
persistence.xml
<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" > <persistence-unit name="MumzJPA" transaction-type="RESOURCE_LOCAL"> <class>com.mumz.test.hibernatesearch.entitybeans.MHSBookEntityBean</class> <class>com.mumz.test.hibernatesearch.entitybeans.MHSBookShelfEntityBean</class> <properties> <property name="hibernate.show_sql" value="true"/> <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/> <property name="hibernate.connection.password" value="root"/> <property name="hibernate.connection.url" value="jdbc:mysql://localhost/jpa_schema"/> <property name="hibernate.connection.username" value="root"/> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> </properties> </persistence-unit> </persistence>
TestOneToManyJoinTable.java
package com.mumz.test.hibernatesearch.entitybeans; import java.util.HashSet; import java.util.Set; import javax.persistence.EntityManager; import javax.persistence.Persistence; /** * The Class TestOneToManyJoinTable. * @author prabhat.jha */ public class TestOneToManyJoinTable { /** * The main method. * * @param args * the arguments */ public static void main(String[] args) { EntityManager entityManager = Persistence.createEntityManagerFactory("MumzJPA").createEntityManager(); try { Set<MHSBookEntityBean> books = new HashSet<MHSBookEntityBean>(); MHSBookEntityBean mhsBookEntityBean = new MHSBookEntityBean(); mhsBookEntityBean.setName("Java EE Pocket Guide"); mhsBookEntityBean.setAuthor("Arun Gupta"); books.add(mhsBookEntityBean); mhsBookEntityBean = new MHSBookEntityBean(); mhsBookEntityBean.setName("Pro Android 4"); mhsBookEntityBean.setAuthor("Satya Komatineni and Dave MacLean"); books.add(mhsBookEntityBean); MHSBookShelfEntityBean bookShelfEntityBean = new MHSBookShelfEntityBean(); bookShelfEntityBean.setName("Technical Books"); bookShelfEntityBean.setBooks(books); entityManager.getTransaction().begin(); entityManager.persist(bookShelfEntityBean); entityManager.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); entityManager.getTransaction().rollback(); } finally { if (entityManager != null) { entityManager.close(); } entityManager = null; } } }
Database schema used for this code.
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL'; DROP SCHEMA IF EXISTS `jpa_schema` ; CREATE SCHEMA IF NOT EXISTS `jpa_schema` DEFAULT CHARACTER SET utf8 ; USE `jpa_schema` ; -- ----------------------------------------------------- -- Table `jpa_schema`.`book_shelf` -- ----------------------------------------------------- DROP TABLE IF EXISTS `jpa_schema`.`book_shelf` ; CREATE TABLE IF NOT EXISTS `jpa_schema`.`book_shelf` ( `BOOK_SHELF_ID` INT(11) NOT NULL AUTO_INCREMENT , `BOOK_SHELF_NAME` VARCHAR(45) NULL DEFAULT NULL , PRIMARY KEY (`BOOK_SHELF_ID`) ) ENGINE = InnoDB DEFAULT CHARACTER SET = utf8; -- ----------------------------------------------------- -- Table `jpa_schema`.`book` -- ----------------------------------------------------- DROP TABLE IF EXISTS `jpa_schema`.`book` ; CREATE TABLE IF NOT EXISTS `jpa_schema`.`book` ( `BOOK_ID` INT(11) NOT NULL AUTO_INCREMENT , `BOOK_AUTHOR` VARCHAR(45) NOT NULL , `BOOK_NAME` VARCHAR(45) NOT NULL , `BOOK_SHELF_ID` INT(11) NULL DEFAULT NULL , PRIMARY KEY (`BOOK_ID`) , INDEX `FK_BOOK_SHELF_ID` (`BOOK_SHELF_ID` ASC) , CONSTRAINT `FK_BOOK_SHELF_ID` FOREIGN KEY (`BOOK_SHELF_ID` ) REFERENCES `jpa_schema`.`book_shelf` (`BOOK_SHELF_ID` ) ON DELETE NO ACTION ON UPDATE NO ACTION) ENGINE = InnoDB DEFAULT CHARACTER SET = utf8; SET SQL_MODE=@OLD_SQL_MODE; SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
I’m brand new to this whole running a blog thing and
placing feedback for back links. I see tons of people are just
putting in comments like “outstanding article” or “great post”.
Isn’t this spammy? How come so many blog sites allow this stuff to
be published?
i think its book_id instead of book_shelf_id in referenced column name : @JoinColumn(name = “BOOK_SHELF_ID”, referencedColumnName = “BOOK_SHELF_ID”)
agree
Did someone try this and work?
Thanks!
Fine way of explaining, and nice post to obtain facts
on the topic of my presentation topic, which i am going
to deliver in school.