I am getting below exception while executing my code. I am not hibernate expert and just started learning it. Please help. what changes need to be done for successful execution of below code. I have added all the code below.
Exception in thread "main" org.hibernate.PropertyValueException: not-null property references a null or transient value: hibernate.Student.officeAddress
at org.hibernate.engine.Nullability.checkNullability(Nullability.java:72)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:284)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:180)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:121)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:186)
at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:33)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:175)
at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:27)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:535)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:523)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:519)
at hibernate.StoreData.main(StoreData.java:44)
Student.java
package hibernate;
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.Id;
import javax.persistence.Lob;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
#Entity
#Table (name="student")
public class Student {
#Id
private int id;
private String firstName;
private String lastName;
private java.util.Date date;
#Embedded
#AttributeOverrides({
#AttributeOverride(name="pincode", column=#Column(name="Home_PIN_Code", nullable=false)),
#AttributeOverride(name="street", column=#Column(name="Home_Street", nullable=false)),
#AttributeOverride(name="city", column=#Column(name="Home_City", nullable=false))
})
private Address homeAddress;
#Embedded
private Address officeAddress;
public Address getHomeAddress() {
return homeAddress;
}
public void setHomeAddress(Address homeAddress) {
this.homeAddress = homeAddress;
}
public Address getOfficeAddress() {
return officeAddress;
}
public void setOfficeAddress(Address officeAddress) {
this.officeAddress = officeAddress;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Column (name="FirstNAME")
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
#Lob
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
#Temporal (TemporalType.TIMESTAMP)
public java.util.Date getDate() {
return date;
}
public void setDate(java.util.Date date2) {
this.date = date2;
}
}
Address.java
package hibernate;
import javax.persistence.Column;
import javax.persistence.Embeddable;
#Embeddable
public class Address {
#Column(name="Pincode",nullable=false)
private int pincode;
#Column(name="Street",nullable=false)
private String street;
#Column(name="City",nullable=false)
private String city;
public int getPincode() {
return pincode;
}
public void setPincode(int pincode) {
this.pincode = pincode;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
StoreData.java
package hibernate;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
public class StoreData {
public static void main(String[] args) {
SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction t=session.beginTransaction();
Student e1=new Student();
e1.setId(1);
e1.setFirstName("Majid");
e1.setLastName("Khan");
e1.setDate(new Date());
Address ad1 = new Address();
ad1.setCity("Mumbai");
ad1.setPincode(400059);
ad1.setStreet("Marol Mahrishi Road");
e1.setHomeAddress(ad1);
Student e2=new Student();
e2.setId(2);
e2.setFirstName("Jayada");
e2.setLastName("Bano");
e2.setDate(new Date());
Address ad2 = new Address();
ad2.setCity("Hindaun");
ad2.setPincode(322230);
ad2.setStreet("Islam Colony");
e2.setOfficeAddress(ad2);
session.save(e1);
session.save(e2);
t.commit();
session.close();
System.out.println("successfully saved");
}
}
officeAddress can not be empty when you initialize values to the Student object
Change private int pincode to private Integer pincode as explained here Hibernate Embedded/Embeddable not null exception
Related
I have just started learning and experimenting with spring-boot and hibernate and there is this problem I can't seem to figure out.
package net.codejava;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.Replace;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.test.annotation.Rollback;
#DataJpaTest
#AutoConfigureTestDatabase(replace = Replace.NONE)
#Rollback(false)
public class UserRepositoryTests {
#Autowired
private UserRepositoryTests repo;
#Autowired
private TestEntityManager entityManager;
#Test
public void testCreateUser() {
User user = new User();
user.setEmail("xyz#gmail.com");
user.setPassword("XYZ!##");
user.setFirstname("XYZ");
user.setLastname("PQR");
user.setUsername("XZY");
User savedUser = repo.save(user);
User existUser = entityManager.find(User.class, savedUser.getIdUser());
assertThat(user.getEmail()).isEqualTo(existUser.getEmail());
}
}
There is some error with line 38 (i.e,User savedUser = repo.save(user);)
is says that"The method save(User) is undefined for the type UserRepositoryTests"
User.java
package net.codejava;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "users")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long idUser;
#Column(nullable = false,unique=true,length = 45)
private String email;
#Column(nullable = false,unique=true,length = 45)
private String firstname;
#Column(nullable = false,unique=true,length = 45)
private String lastname;
#Column(nullable = false,unique=true,length = 45)
private String username;
#Column(nullable = true)
private String IPaddress;
#Column(nullable = false,length = 64)
private String password;
public Long getIdUser() {
return idUser;
}
public void setIdUser(Long idUser) {
this.idUser = idUser;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getIPaddress() {
return IPaddress;
}
public void setIPaddress(String iPaddress) {
IPaddress = iPaddress;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
UserRepository.java
package net.codejava;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
}
Please let me know what to do.
the problem was UserRepositoryTests it should have been UserRepository.
I am trying to build a Spring Boot application that uses 2 data sources. My primary database for now is the in-memory database (just for testing purposes) with tables that are populated with the help of the sql file that I have created. The other database(oracledb) has tables that are already populated.
What am I trying to achieve?
I am trying to pull data from oracledb, process it and populate tables in h2 database.
What is the problem I am facing?
I only want the entities for the h2 db be created as tables in the in-mem database (I want to be able to specify h2 which entities to scan and create tables, not all the classes that have #Entity annotation). All of the classes that have #Entity are being created as tables in my in-mem database and that is what I am trying to avoid.
What have I tried?
I created two separate packages for the entities belonging to h2 and oracledb and using #EntityScan I only scanned the package that had entities for h2. This worked, however, I need the other entities for oracledb to be scanned so I am able to use them.
Code Snippet of what I have:
My applications.properties file
#spring.jpa.hibernate.ddl-auto=none
spring.jpa.generate-ddl=true
spring.h2.console.enabled=true
spring.h2.console.path=/h2
# first data source
spring.datasource.url=jdbc:h2:mem:mydb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.application.name=Health Monitor
## 2nd data source
spring.production-datasource.url= jdbc:oracle://localhost:3306/db2
spring.production-datasource.driverClassName=oracle.jdbc.driver.OracleDriver
spring.production-datasource.username=abcd
spring.production-datasource.password=xyz123
DemoApplication.java
package com.automation.demo;
import java.sql.SQLException;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.Bean;
#SpringBootApplication
//#EntityScan( basePackages = {"domain"} )
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#Bean(initMethod = "start", destroyMethod = "stop")
public org.h2.tools.Server inMemoryH2DatabaseaServer() throws SQLException {
return org.h2.tools.Server.createTcpServer(
"-tcp", "-tcpAllowOthers", "-tcpPort", "9090");
}
}
ConfigureDB.java
package com.automation.demo.configurations;
import javax.sql.DataSource;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import com.zaxxer.hikari.HikariDataSource;
#Configuration
public class ConfigureDB {
#Primary
#Bean
#ConfigurationProperties(prefix="spring.datasource")
public DataSourceProperties devDataSourceProperties() {
return new DataSourceProperties();
}
#Bean
#Primary
#ConfigurationProperties("spring.datasource.configuration")
public DataSource devDataSource() {
return devDataSourceProperties().initializeDataSourceBuilder()
.type(HikariDataSource.class).build();
}
#Bean
#ConfigurationProperties("spring.production-datasource")
public DataSourceProperties productionDataSourceProperties() {
return new DataSourceProperties();
}
#Bean
#ConfigurationProperties("spring.production-datasource.configuration")
public DataSource productionDataSource() {
return productionDataSourceProperties().initializeDataSourceBuilder()
.type(HikariDataSource.class).build();
}
}
Employee.java (for the h2 database)
package com.automation.demo.dev.entities;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="test")
public class Employee {
// define fields
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="ID")
private int id;
#Column(name="FirstName")
private String firstName;
#Column(name="LastName")
private String lastName;
#Column(name="Email")
private String email;
// define constructors
public Employee() {
}
public Employee(String firstName, String lastName, String email) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
// define getter/setter
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
// define tostring
#Override
public String toString() {
return "Employee [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", email=" + email + "]";
}
}
CustomerInfo.java (this is the entity representing a table in oracledb, I want to prevent a table representing this entity to be created in the h2 database)
package com.automation.demo.production.entities;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="customer")
public class CustomerInfo {
// define fields
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="ID")
private int id;
#Column(name="FirstName")
private String firstName;
#Column(name="LastName")
private String lastName;
#Column(name="Email")
private String email;
// define constructors
public CustomerInfo() {
}
public CustomerInfo(String firstName, String lastName, String email) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
// define getter/setter
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
// define tostring
#Override
public String toString() {
return "Customer [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", email=" + email + "]";
}
}
Please let me know if I have missed anything. Also, if there are any other mistakes I have made but are not related to my current problem please mention those as well.
Thanks.
Hibernate has a way to do this with SchemaFilterProvider.
SchemaFilterProvider
public class MySchemaFilterProvider implements SchemaFilterProvider {
#Override
public SchemaFilter getCreateFilter() {
return MySchemaFilter.INSTANCE;
}
#Override
public SchemaFilter getDropFilter() {
return MySchemaFilter.INSTANCE;
}
#Override
public SchemaFilter getMigrateFilter() {
return MySchemaFilter.INSTANCE;
}
#Override
public SchemaFilter getValidateFilter() {
return MySchemaFilter.INSTANCE;
}
}
SchemaFilter
public class MySchemaFilter implements SchemaFilter {
public static final MySchemaFilter INSTANCE = new MySchemaFilter();
#Override
public boolean includeNamespace(Namespace namespace) {
return true;
}
#Override
public boolean includeTable(Table table) {
if (table.getName().equals("customer")) {
return false;
}
return true;
}
#Override
public boolean includeSequence(Sequence sequence) {
return true;
}
}
Spring property configuration
spring.jpa.properties.hibernate.hbm2ddl.schema_filter_provider=MySchemaFilterProvider
Note - With Springboot the property is: spring.jpa.properties.hibernate.hbm2ddl.schema_filter_provider=xxx
I want retrieve user email from MySql database table using spring boot.i used findByEmailAndPassword in controller but it retrieve null value for email.
Here is my Code
controller
package com.example.demo.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.example.demo.JPARepository;
import com.example.demo.pojo.regisbean;
#Controller
public class registerController {
regisbean pp;
#RequestMapping(value = "/")
public String mm() {
System.out.println("I am in m1 method");
return "index";
}
#RequestMapping(value = { "/register", "home" })
public String m1() {
System.out.println("I am in mm method");
return "register";
}
#Autowired
JPARepository jpaRepository;
#PostMapping("/register")
public String regis(#ModelAttribute regisbean rb)
{
System.out.println("I m in regis method");
regisbean b=jpaRepository.save(rb);
if(b!=null)
return "index";
else
return "fail";
}
#RequestMapping(value= {"/login1","login2"})
public String m2() {
System.out.println("i m in m2()");
return "login";
}
#PostMapping("/login")
public String login(#ModelAttribute regisbean rx,Model m) {
System.out.println("I am in Login");
regisbean re=jpaRepository.findByEmailAndPassword(rx.getEmail(), rx.getPassword());
if(re!=null)
{
m.addAttribute("email",rx.getEmail());
m.addAttribute("password",rx.getPassword());
System.out.println("yes");
return "loginsuccess";
}
else
{
System.out.println(rx.getEmail());
System.out.println("failed");
return "register";
}
}
}
pojo class
package com.example.demo.pojo;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "pro")
public class regisbean {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Column
private String name;
#Column
private String email;
#Column
private String phonenumber;
#Column
private String password;
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;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhonenumber() {
return phonenumber;
}
public void setPhonenumber(String phonenumber) {
this.phonenumber = phonenumber;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
Repository
package com.example.demo;
import org.springframework.data.repository.CrudRepository;
import com.example.demo.pojo.regisbean;
public interface JPARepository extends CrudRepository<regisbean, Integer> {
public regisbean findByEmailAndPassword(String email,String password);
}
I was able to get your code to work by inserting a row in the table:
INSERT INTO pro (
id
,email
,name
,password
,phonenumber
)
VALUES (
0
,'user#domain.com'
,'Jim'
,'secret'
,'123-123-1234'
)
Then changing:
public String login(#ModelAttribute regisbean rx,Model m) {
to:
public String login(#RequestBody RegisBean rx,Model m) {
and POSTing the following request body to the /login resource:
{
"email": "user#domain.com",
"password": "secret"
}
I didn't have to make any changes to your Repo. I suspect your attempt was failing because RegisBean was never being initialized with any values and so the repo was asked to find a record with a null email and a null password.
I want to add the following database-structure to my Jpa:
CREATE TABLE USER (
id int PRIMARY KEY AUTO_INCREMENT,
firstname varchar(255),
lastname varchar(255)
);
CREATE TABLE PROJECT (
PNUM varchar(255) PRIMARY KEY,
PNAME varchar(255) NOT NULL
);
CREATE TABLE ROLE (
id int PRIMARY KEY AUTO_INCREMENT,
description varchar(255) NOT NULL
);
CREATE TABLE ASSIGNMENT (
user_id int,
project_num varchar(255),
role_id int,
foreign key (user_id) REFERENCES USER(ID),
FOREIGN KEY (project_num) REFERENCES PROJECT(PNUM),
FOREIGN KEY (role_id) REFERENCES ROLE(id),
PRIMARY KEY (user_id, project_num, role_id)
);
So I started off making the three Entities User, Project and Role (See end of this post for full classes). Then I created the Assignment-class for the connection including an #EmbeddedId:
The Assigment class:
package com.demo.example.entity;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
#Entity
public class Assignment {
#EmbeddedId
private AssignmentId id;
public Assignment() {
// TODO Auto-generated constructor stub
}
public AssignmentId getId() {
return this.id;
}
public void setId(AssignmentId id) {
this.id = id;
}
}
The AssignmentId-class
package com.demo.example.entity;
import java.io.Serializable;
import javax.persistence.Embeddable;
#Embeddable
public class AssignmentId implements Serializable {
private Role role;
private Project project;
private User user;
public AssignmentId(Project project, Role role, User user) {
this.project = project;
this.role = role;
this.user = user;
}
public Project getProject() {
return project;
}
public void setProject(Project project) {
this.project = project;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
Finally I declared the repository for the Assignment:
package com.demo.example.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.demo.example.entity.Assignment;
import com.demo.example.entity.AssignmentId;
#Repository
public interface AssignmentRepository extends JpaRepository<Assignment, AssignmentId> {
}
Now upon running a JUnit-Test I run into the following error:
Caused by: org.hibernate.AnnotationException: A Foreign key refering com.demo.example.entity.Assignment from com.demo.example.entity.User has the wrong number of column. should be 3
I have seen quite a few suggestions on what to do but none of them worked (also, most of the time the "should be"-value is 2. Is this even working out with 3?). But I cannot make out why my User-Entity has a wrong number of columns? It provided three in the #JoinTable-Annotation (one join and two inverseJoin-Columns). What did I do wrong?
The classes:
User.java:
package com.demo.example.entity;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
#Entity
#Table(name="USER")
public class User {
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="user_id")
private int user_id;
#Column(name="firstname")
private String firstname;
#Column(name="lastname")
private String lastname;
#ManyToMany(cascade= {CascadeType.ALL})
#JoinTable(
name="ASSIGNMENT",
joinColumns = {#JoinColumn(name="user_id")},
inverseJoinColumns = { #JoinColumn(name="pnum"),
#JoinColumn(name="role_id")}
)
private Set<Assignment> assignments = new HashSet<Assignment>();
public Set<Assignment> getAssignments() {
return this.assignments;
}
public User() {
}
public User(String firstname, String lastname) {
this.firstname = firstname;
this.lastname = lastname;
}
public void setId(int id) {
this.user_id = id;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public int getId() {
return user_id;
}
public String getFirstname() {
return firstname;
}
public String getLastname() {
return lastname;
}
}
Project.java:
package com.demo.example.entity;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
#Entity
#Table(name="PROJECT")
public class Project {
#Id
#Column(name="PNUM")
private String pnum;
#Column(name = "PNAME", nullable = false)
private String pname;
#ManyToMany(cascade= {CascadeType.ALL})
#JoinTable(
name="ASSIGNMENT",
joinColumns = {#JoinColumn(name="pnum")},
inverseJoinColumns = { #JoinColumn(name="user_id"),
#JoinColumn(name="role_id")}
)
private Set<Assignment> assignments = new HashSet<Assignment>();
public Set<Assignment> getAssignments() {
return this.assignments;
}
public Project() {
// TODO Auto-generated constructor stub
}
public Project(String PNUM, String PNAME) {
this.pnum = PNUM;
this.pname = PNAME;
}
public String getPnum() {
return pnum;
}
public void setPnum(String pnum) {
this.pnum = pnum;
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
}
Role.java:
package com.demo.example.entity;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
#Entity
#Table(name="ROLE")
public class Role {
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="role_id")
private int role_id;
#Column(name = "NAME", nullable = false)
private String name;
#ManyToMany(cascade= {CascadeType.ALL})
#JoinTable(
name="ASSIGNMENT",
joinColumns = {#JoinColumn(name="role_id")},
inverseJoinColumns = { #JoinColumn(name="user_id"),
#JoinColumn(name="project_id")}
)
private Set<Assignment> assignments = new HashSet<Assignment>();
public Set<Assignment> getAssignments() {
return this.assignments;
}
public Role(String name) {
this.name = name;
}
public int getId() {
return this.role_id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
I am new to Hibernate and I am trying to understand the oneToMany concept. I have created two entities which are Person and Book. A person can borrow many books and a book can only have one person borrowing it. So I have made the following classes
Person.java
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.hibernate.annotations.GenericGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
#Entity
#Table(name="PERSON")
public class Person {
private static final Logger _logger = LoggerFactory.getLogger(Person.class);
#Id
#GenericGenerator(name="adder", strategy="increment")
#GeneratedValue(generator="adder")
#Column(name="PID")
private Long id;
#Column(name="FIRSTNAME")
private String firstName;
#Column(name="LASTNAME")
private String lastName;
#Column(name="BIRTHDATE")
#Temporal(TemporalType.DATE)
private Date birthDate;
//add genre and books
#OneToMany(orphanRemoval=true, mappedBy="person", cascade=CascadeType.ALL,targetEntity=Book.class)
private Set<Book> listOfBooks = new HashSet<Book>();
public Set<Book> getListOfBooks() {
return listOfBooks;
}
public void setListOfBooks(Set<Book> listOfBooks) {
this.listOfBooks = listOfBooks;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
//add constructor with all the details
}
Book.java
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
#Entity
#Table(name="BOOK")
public class Book {
private static final Logger logger = LoggerFactory.getLogger(Book.class);
#Id
#GenericGenerator(name="adder", strategy="increment")
#GeneratedValue(generator="adder")
private Long bookId;
#Column(name="NAME")
private String name;
#Column(name="AUTHOR")
private String author;
#Column(name="PUBLICATION_YEAR")
private int yearOfPublication;
#Column(name="PUBLISHER")
private String publisher;
#ManyToOne()
#JoinColumn(name="PERSON_ID")
private Person person;
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public Long getBookId() {
return bookId;
}
public void setBookId(Long bookId) {
this.bookId = bookId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public int getYearOfPublication() {
return yearOfPublication;
}
public void setYearOfPublication(int yearOfPublication) {
this.yearOfPublication = yearOfPublication;
}
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
}
HibernateLibraryDaoMain.java
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import se325.project.assignment1.hibernate.domain.Book;
import se325.project.assignment1.hibernate.domain.Person;
public class HibernateLibraryDaoMain {
public static void main(String[] args) {
Person person = new Person();
person.setFirstName("Bob");
person.setLastName("Marley");
person.setBirthDate(new Date());
Book book = new Book();
book.setName("Bob Marley book");
book.setAuthor("Lily Marley");
book.setPublisher("Marley Publications");
book.setYearOfPublication(2000);
Book book1 = new Book();
book1.setName("Laura Marley book");
book1.setAuthor("Laura Marley");
book1.setPublisher("Laura Publications");
book1.setYearOfPublication(2005);
person.getListOfBooks().add(book);
person.getListOfBooks().add(book1);
book.setPerson(person);
book1.setPerson(person);
Configuration configuration = new Configuration();
configuration.configure("se325/project/assignment1/hibernate/hibernate.cfg.xml");
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties()).build();
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(person);
session.save(book);
session.save(book1);
session.getTransaction().commit();
session.close();
}
}
The problem is that Hibernate does not create a separate Table that illustrates the oneToMany relationship. I can't seem to find the problem. Any help would be appreciated.
I understand where I went wrong. When I have a mappedBy property set, then Hibernate doesn't create a third table but instead it adds to the Entity that has the ManyToOne and joinColumn property. Thanks to all the users that helped :)