JPA OneToMany Unidirectional without Join Table

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

[sourcecode language=”xml”]
<project
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance&quot;
xmlns="http://maven.apache.org/POM/4.0.0&quot;
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;
>
<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&gt;
<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>
[/sourcecode]

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

[sourcecode language=”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 + "]";
}
}
[/sourcecode]

Next we will write our MHSBookShelfEntityBean

MHSBookShelfEntityBean.java

[sourcecode language=”java” highlight=”86,87″]
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 + "]";
}
}
[/sourcecode]

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
[sourcecode language=”xml”]
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance&quot;
version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence&quot;
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd&quot; >
<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>
[/sourcecode]
TestOneToManyJoinTable.java
[sourcecode language=”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;
}
}
}
[/sourcecode]

Database schema used for this code.
[sourcecode language=”sql”]
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;
[/sourcecode]


Posted

in

, , , , ,

by

Tags:

Comments

5 responses to “JPA OneToMany Unidirectional without Join Table”

  1. Archie Avatar

    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?

  2. jayendra Avatar
    jayendra

    i think its book_id instead of book_shelf_id in referenced column name : @JoinColumn(name = “BOOK_SHELF_ID”, referencedColumnName = “BOOK_SHELF_ID”)

    1. Alex Avatar

      agree

  3. Andrea Avatar
    Andrea

    Did someone try this and work?
    Thanks!

  4. Levi Avatar

    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.

Leave a Reply

Discover more from Code Holic

Subscribe now to keep reading and get access to the full archive.

Continue reading