I have one parent object as Employee and child object as Address. I just need to update the both objects using Employee object. But when updating using employee object i just getting emp_id should not be null. Here is my table and entity
CREATE TABLE `employee` (
`employee_id` bigint(20) NOT NULL AUTO_INCREMENT,
`employee_name` varchar(30) NOT NULL,
`employee_desg` varchar(30) NOT NULL,
`salary` varchar(30) NOT NULL,
`employee_reference_id` varchar(10) NOT NULL,
PRIMARY KEY (`employee_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
Address table
CREATE TABLE `address` (
`address_id` bigint(20) NOT NULL AUTO_INCREMENT,
`emp_id` bigint(20) NOT NULL,
`address` varchar(255) NOT NULL,
PRIMARY KEY (`address_id`),
KEY `employee_address` (`emp_id`),
CONSTRAINT `employee_address` FOREIGN KEY (`emp_id`) REFERENCES `employee` (`employee_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
Employee Object
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
#Entity
#Table(name = "Employee")
public class Employee {
#Id
#GeneratedValue
#Column(name = "EMPLOYEE_ID")
private int id;
#Column(name = "EMPLOYEE_NAME")
private String employeeName;
#Column(name = "EMPLOYEE_DESG")
private String employeeDesg;
#Column(name = "SALARY")
private String salary;
#Column(name = "EMPLOYEE_REFERENCE_ID")
private String employeeReferenceId;
public String getEmployeeReferenceId() {
return employeeReferenceId;
}
public void setEmployeeReferenceId(String employeeReferenceId) {
this.employeeReferenceId = employeeReferenceId;
}
#OneToOne(mappedBy="employee", cascade = CascadeType.ALL)
private Address address;
public String getEmployeeName() {
return employeeName;
}
public void setEmployeeName(String employeeName) {
this.employeeName = employeeName;
}
public String getEmployeeDesg() {
return employeeDesg;
}
public void setEmployeeDesg(String employeeDesg) {
this.employeeDesg = employeeDesg;
}
public String getSalary() {
return salary;
}
public void setSalary(String salary) {
this.salary = salary;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
Address Object
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
#Entity
#Table(name = "ADDRESS")
public class Address {
#Id
#Column(name="ADDRESS_ID")
#GeneratedValue(strategy=GenerationType.AUTO)
private int id;
#Column(name = "ADDRESS")
private String address;
#OneToOne(fetch=FetchType.EAGER , cascade=CascadeType.ALL, orphanRemoval=true)
#JoinColumn(name="emp_id",referencedColumnName="employee_id")
private Employee employee;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
public Address() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
My code is
public class StudentUtil1To1 {
public static void main(String args[]){
SessionFactory factory=null;
Configuration configuration=null;
ServiceRegistry registry=null;
Session session=null;
try{
configuration= new Configuration();
configuration.configure();
registry=new StandardServiceRegistryBuilder().configure().applySettings(configuration.getProperties()).build();
factory=configuration.configure("hibernate.cfg.xml").buildSessionFactory(registry);
session= factory.openSession();
session.beginTransaction();
Employee emp=new Employee();
emp.setId(1);
emp.setEmployeeReferenceId("CP001");
emp.setEmployeeName("Muthu");
emp.setEmployeeDesg("Developer");
emp.setSalary("15000");
Address address=new Address();
address.setAddress("3, Civil aerodrome, CBE");
emp.setAddress(address);
address.setEmployee(emp);
session.update(emp);
System.out.println("Successfuly Saved");
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
}finally{
if(session!=null){
session.close();
}
if(factory!=null){
factory.close();
}
}
}
}
And the error is
09:40:48.815 [http-nio-8081-exec-7] WARN o.h.e.jdbc.spi.SqlExceptionHelper - SQL Error: 1048, SQLState: 23000
09:40:48.816 [http-nio-8081-exec-7] ERROR o.h.e.jdbc.spi.SqlExceptionHelper - Column 'emp_id' cannot be null
What i need to for update. Correct my mistake.
Since you have already mapped Address entity in employee entity like this
#OneToOne(mappedBy="employee", cascade = CascadeType.ALL)
private Address address;
You dont have to do same thing in address class means
#OneToOne(fetch=FetchType.EAGER , cascade=CascadeType.ALL, orphanRemoval=true)
#JoinColumn(name="emp_id",referencedColumnName="employee_id")
private Employee employee;
Above code is not required in address entity.And remove the employee attribute from address class.
Now you already added the CascadeType.ALL in OneToOne annotation and save only employee object like this
Employee emp=new Employee();
Address address=new Address("your address");
emp.setAddress(address);
emp.setId(1);
emp.setEmployeeReferenceId("CP001");
emp.setEmployeeName("Muthu");
emp.setEmployeeDesg("Developer");
emp.setSalary("15000");
session.update(emp);
1.#MapppedBy annotation means:the entity annotationed by #MapppedBy,give up the reference of key,so in the employee table,dont have the column named "address_id".
the relation between Employee and Address controlled by "address" table.
2. when you use [session.update(emp);],you havent have the data of "Employee" table.but emp_id is the FOREIGN KEY,so will occur this problem
3. i can first insert Employee,then [session.update(emp);]
Related
I created two table and they are linked together by foreign key.
Table: users
Id name address_id
1 John 1
2 William 2
3 Scott 1
4 Mary 1
Table: Address
Id city
1 USA
2 Frank
This is Entity
User.java
package com.example.demo.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Table(name = "users")
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(name = "name")
private String name;
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "address_id")
private Address address;
public User () {}
public User (String name) {
this.name=name;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
Address.java
package com.example.demo.model;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
#Table(name = "address")
#Entity
public class Address {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String city;
#OneToMany(mappedBy = "address", cascade = CascadeType.ALL)
private Set<User> users= new HashSet<>();
public Address () {}
public Address (String city) {
this.city=city;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
}
I have successfully created, modified, and deleted functions. I am trying to create a function to list the list by same value but still with no success. For example, if I want to list all "names" with address "1", it will output the values "John", "William", "Mary". I tried to use #Query but it also failed. Any suggestions or sample code for me? Thanks very much
Entity Class UserExtraDetails with having one to one relationship with APP_USER with column SSO_ID
package com.eportal.models;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToOne;
import javax.persistence.Table;
#Entity
#Table(name = "userdetails")
public class userExtraDetails implements Serializable {
#Column(name = "Address", nullable = true)
private String Address;
#Id
#Column(name = "SSO_ID", nullable = false)
private String ssoId;
#Column(name = "City", nullable = true)
private String City;
#Column(name = "Country", nullable = true)
private String Country;
#Column(name = "Postal_Code", nullable = true)
private String Postal_Code;
#Column(name = "about_me", nullable = true)
private String about_me;
#OneToOne(fetch = FetchType.LAZY)
#JoinTable(name = "APP_USER", joinColumns = { #JoinColumn(name = "SSO_ID") })
private User user;
public String getAbout_me() {
return about_me;
}
public String getSsoId() {
return ssoId;
}
public void setSsoId(String ssoId) {
this.ssoId = ssoId;
}
public void setAbout_me(String about_me) {
this.about_me = about_me;
}
public String getAddress() {
return Address;
}
public void setAddress(String address) {
Address = address;
}
public String getCity() {
return City;
}
public void setCity(String city) {
City = city;
}
public String getCountry() {
return Country;
}
public void setCountry(String country) {
Country = country;
}
public String getPostal_Code() {
return Postal_Code;
}
public void setPostal_Code(String postal_Code) {
Postal_Code = postal_Code;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
Entity Class User with a one to one relationship with userdetails with column SSO_ID
package com.eportal.models;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
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.OneToOne;
import javax.persistence.Table;
import org.hibernate.validator.constraints.NotEmpty;
#Entity
#Table(name = "APP_USER")
public class User implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#NotEmpty
#Column(name = "SSO_ID", unique = true, nullable = false)
private String ssoId;
#NotEmpty
#Column(name = "PASSWORD", nullable = false)
private String password;
#NotEmpty
#Column(name = "FIRST_NAME", nullable = false)
private String firstName;
#NotEmpty
#Column(name = "LAST_NAME", nullable = false)
private String lastName;
#NotEmpty
#Column(name = "EMAIL", nullable = false)
private String email;
#OneToOne(fetch = FetchType.LAZY)
#JoinTable(name = "userdetails", joinColumns = { #JoinColumn(name = "SSO_ID") })
private userExtraDetails details;
#NotEmpty
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name = "APP_USER_USER_PROFILE", joinColumns = { #JoinColumn(name = "USER_ID") }, inverseJoinColumns = {
#JoinColumn(name = "USER_PROFILE_ID") })
private Set<UserProfile> userProfiles = new HashSet<UserProfile>();
public userExtraDetails getDetails() {
return details;
}
public void setDetails(userExtraDetails details) {
this.details = details;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getSsoId() {
return ssoId;
}
public void setSsoId(String ssoId) {
this.ssoId = ssoId;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
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;
}
public Set<UserProfile> getUserProfiles() {
return userProfiles;
}
public void setUserProfiles(Set<UserProfile> userProfiles) {
this.userProfiles = userProfiles;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((ssoId == null) ? 0 : ssoId.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof User))
return false;
User other = (User) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (ssoId == null) {
if (other.ssoId != null)
return false;
} else if (!ssoId.equals(other.ssoId))
return false;
return true;
}
/*
* DO-NOT-INCLUDE passwords in toString function. It is done here just for
* convenience purpose.
*/
#Override
public String toString() {
return "User [id=" + id + ", ssoId=" + ssoId + ", password=" + password + ", firstName=" + firstName
+ ", lastName=" + lastName + ", email=" + email + "]";
}
}
18:31:55.434 [localhost-startStop-1] ERROR o.h.tool.hbm2ddl.SchemaUpdate - HHH000388: Unsuccessful: alter table APP_USER add constraint FK_1wjx4w75wu94ftp6jvt35krf0 foreign key (user_id) references APP_USER
18:31:55.434 [localhost-startStop-1] ERROR o.h.tool.hbm2ddl.SchemaUpdate - There is already an object named 'FK_1wjx4w75wu94ftp6jvt35krf0' in the database.
18:31:55.438 [localhost-startStop-1] ERROR o.h.tool.hbm2ddl.SchemaUpdate - HHH000388: Unsuccessful: alter table APP_USER add constraint FK_hqk6uc88j3imq8u9jhro36vt3 foreign key (SSO_ID) references userdetails
18:31:55.438 [localhost-startStop-1] ERROR o.h.tool.hbm2ddl.SchemaUpdate - The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK_hqk6uc88j3imq8u9jhro36vt3". The conflict occurred in database "CloudDB", table "dbo.userdetails", column 'SSO_ID'.
18:31:55.440 [localhost-startStop-1] ERROR o.h.tool.hbm2ddl.SchemaUpdate - HHH000388: Unsuccessful: alter table APP_USER_USER_PROFILE add constraint FK_brmce0t584euix4wb4rursf1q foreign key (USER_ID) references APP_USER
18:31:55.440 [localhost-startStop-1] ERROR o.h.tool.hbm2ddl.SchemaUpdate - There is already an object named 'FK_brmce0t584euix4wb4rursf1q' in the database.
18:31:55.442 [localhost-startStop-1] ERROR o.h.tool.hbm2ddl.SchemaUpdate - HHH000388: Unsuccessful: alter table userdetails add constraint FK_pffebqmeoi5qdq5g63w450h1i foreign key (SSO_ID) references APP_USER
18:31:55.442 [localhost-startStop-1] ERROR o.h.tool.hbm2ddl.SchemaUpdate - Column 'APP_USER.id' is not the same data type as referencing column 'userdetails.SSO_ID' in foreign key 'FK_pffebqmeoi5qdq5g63w450h1i'.
18:31:55.442 [localhost-startStop-1] INFO o.h.tool.hbm2ddl.SchemaUpdate - HHH000232: Schema update complete
The following error is shown:
Unsuccessful: alter table APP_USER add constraint
FK_1wjx4w75wu94ftp6jvt35krf0 foreign key (user_id) references APP_USER
There is already an object named 'FK_1wjx4w75wu94ftp6jvt35krf0' in the
database.
Unsuccessful: alter table APP_USER add constraint
FK_hqk6uc88j3imq8u9jhro36vt3 foreign key (SSO_ID) references
userdetails
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint
"FK_hqk6uc88j3imq8u9jhro36vt3". The conflict occurred in database
"CloudDB", table "dbo.userdetails", column 'SSO_ID'.
Unsuccessful: alter table APP_USER_USER_PROFILE add constraint
FK_brmce0t584euix4wb4rursf1q foreign key (USER_ID) references APP_USER
There is already an object named 'FK_brmce0t584euix4wb4rursf1q' in the
database.
Unsuccessful: alter table userdetails add constraint
FK_pffebqmeoi5qdq5g63w450h1i foreign key (SSO_ID) references APP_USER
Column 'APP_USER.id' is not the same data type as referencing column
'userdetails.SSO_ID' in foreign key 'FK_pffebqmeoi5qdq5g63w450h1i'.
I have 2 class Employee and Passport, then I tried to create a one to one mapping with Primary and Foreign Key Relationship with Annotations, but the foreign key relationship is not happening in Passport table.
Here Primary_Id is Emp_No in Employee table and must be a foreign Key in Passport table.
Below i have provided the 2 POJO classes for Employee and Passport and also the generated SQL from Hibernate.
Could somebody help me where I make mistake. Kindly let me know in case of further information.
Employee
package com.otr.hibernate;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
/**
*
* #author SPAR
*/
#Entity
public class Employee implements Serializable {
#Id
private String emp_No;
private String first_Name;
private String second_Name;
private String designation;
public String getEmp_No() {
return emp_No;
}
public void setEmp_No(String emp_No) {
this.emp_No = emp_No;
}
public String getFirst_Name() {
return first_Name;
}
public void setFirst_Name(String first_Name) {
this.first_Name = first_Name;
}
public String getSecond_Name() {
return second_Name;
}
public void setSecond_Name(String second_Name) {
this.second_Name = second_Name;
}
public String getDesignation() {
return designation;
}
public void setDesignation(String designation) {
this.designation = designation;
}
}
Passport.java
package com.otr.hibernate;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;
/**
*
* #author SPAR
*/
#Entity
public class Passport implements Serializable {
private String passport_No;
#Id #GeneratedValue(generator = "foreign")
#GenericGenerator(name= "foreign", strategy = "foreign", parameters = {#Parameter(value = "employee", name = "property")})
private String emp_RN_No;
#OneToOne (cascade = CascadeType.ALL)
#JoinColumn(name = "emp_RN_No")
private Employee employee;
public String getPassport_No() {
return passport_No;
}
public void setPassport_No(String passport_No) {
this.passport_No = passport_No;
}
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
public String getEmp_No() {
return emp_No;
}
public void setEmp_RN_No(String emp_No) {
this.emp_No = emp_No;
}
}
Hibernate Generation
Hibernate: create table Employee (emp_No varchar(255) not null, designation varchar(255), first_Name varchar(255), second_Name varchar(255), primary key (emp_No));
Hibernate: create table Passport (emp_No varchar(255) not null, passport_No varchar(255), primary key (emp_No));
You don't need the GenericGenerator to do that. There are two simpler alternatives:
Combine #Id and #OneToOne:
#Id #OneToOne (cascade = CascadeType.ALL)
#JoinColumn(name = "emp_RN_No")
private Employee employee;
Make sure you remove the previous #Id property emp_RN_No
Using #MapsId:
#Id
private String emp_RN_No;
#MapsId #OneToOne
#JoinColumn(name = "emp_RN_No")
private Employee employee;
I am new to Hibernate, so please forgive me if the question is duplicated or stupid. I am using Hibernate 3.3.0, PostgreSQL DB. Right now I have 2 entities. I need to associate them with #OneToMany annotation in such way, that User.roleID was PK and Role.id was FK (user can have only one role, and the same role can be assigned to many users). Also as I was searching Google, I found out that for some reason every example with annotation associations has the annotated field declared as Set. Please, explain this to me. Thank you in advice.
Nazar.
User entity:
package com.dataart.mediaportal.model;
import java.io.Serializable;
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 implements Serializable {
private int id;
private String login;
private String password;
private String firstName;
private String lastName;
private int roleID;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "user_id", unique = true)
public int getId() {
return id;
}
#Column(name = "user_login", nullable=false, unique = true, length = 20 )
public String getLogin() {
return login;
}
#Column(name = "user_password", nullable = false, length = 32)
public String getPassword() {
return password;
}
#Column(name = "user_name", nullable = true)
public String getFirstName() {
return firstName;
}
#Column(name = "user_lastname", nullable = true)
public String getLastName() {
return lastName;
}
#Column(name = "role_id", nullable = false)
public int getRoleID() {
return roleID;
}
public void setRoleID(int roleID) {
this.roleID = roleID;
}
public void setId(int id) {
this.id = id;
}
public void setLogin(String login) {
this.login = login;
}
public void setPassword(String password) {
this.password = password;
}
public void setFirstName(String firstname) {
this.firstName = firstname;
}
public void setLastName(String lastname) {
this.lastName = lastname;
}
}
Role entity:
package com.dataart.mediaportal.model;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "roles")
public class Role implements Serializable {
private int id;
private String role;
#Id
#Column(name = "role_id", nullable = false)
public int getId() {
return id;
}
#Column(name = "role_name", nullable = false)
public String getRole() {
return role;
}
public void setId(int id) {
this.id = id;
}
public void setRole(String role) {
this.role = role;
}
}
DB Script:
DROP TABLE IF EXISTS users CASCADE;
DROP TABLE IF EXISTS roles CASCADE;
DROP TABLE IF EXISTS albums CASCADE;
DROP TABLE IF EXISTS images CASCADE;
CREATE TABLE users
(
user_login character varying(20) NOT NULL,
user_password character varying(32) NOT NULL,
user_name character varying,
user_lastname character varying,
role_id integer DEFAULT 0,
user_id serial NOT NULL,
CONSTRAINT pk_user_id PRIMARY KEY (user_id),
CONSTRAINT users_user_login_key UNIQUE (user_login)
)
WITH (
OIDS=FALSE
);
ALTER TABLE users
OWNER TO postgres;
CREATE TABLE roles
(
role_id integer NOT NULL,
role_name character varying NOT NULL DEFAULT 'user'::character varying,
CONSTRAINT role_id_pk PRIMARY KEY (role_id)
)
WITH (
OIDS=FALSE
);
ALTER TABLE roles
OWNER TO postgres;
INSERT INTO roles
VALUES ( 0, 'user' ),
( 1, 'admin' );
-- testlog - testpass
-- user - password
INSERT INTO users
VALUES ( 'testlog', '179ad45c6ce2cb97cf1029e212046e81', 'Nazar', 'Sobchuk', 1),
('user', '5f4dcc3b5aa765d61d8327deb882cf99', 'unknown', 'unknown', 0);
CREATE TABLE albums
(
album_name character varying NOT NULL,
user_id integer,
album_id serial NOT NULL,
CONSTRAINT album_id PRIMARY KEY (album_id),
CONSTRAINT user_id FOREIGN KEY (user_id)
REFERENCES users (user_id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
OIDS=FALSE
);
ALTER TABLE albums
OWNER TO postgres;
CREATE INDEX fki_user_id
ON albums
USING btree
(user_id);
INSERT INTO albums VALUES ('Main Album', 1);
CREATE TABLE images
(
img bytea,
img_name character varying NOT NULL,
album_id integer,
img_id serial NOT NULL,
CONSTRAINT images_img_name UNIQUE(img_name),
CONSTRAINT album_id FOREIGN KEY (album_id)
REFERENCES albums (album_id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
OIDS=FALSE
);
ALTER TABLE images
OWNER TO postgres;
CREATE INDEX fki_album_id
ON images
USING btree
(album_id);
Insert user:
public boolean insertUser(User user) {
factory = getSessionFactory();
session = factory.openSession();
tx = session.beginTransaction();
Query queryResult = session.createQuery("from User");
List<User> userList = queryResult.list();
for (User u : userList) {
if (u.getLogin().equalsIgnoreCase(user.getLogin())) {
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage("User_is_already_registered"));
return false;
}
}
session.save(user);
tx.commit();
session.close();
return true;
}
Add the user as one to many relationship to Role as below. create the setters as well
private List<User> userList;
#OneToMany(mappedBy = "role")
public List<User> getUserList() {
return userList;
}
Add the Role as many to one relationship to User as below
private Role role;
#ManyToOne
public Role getRole() {
return role;
}
I have the following database structure:
CREATE TABLE `author` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
PRIMARY KEY (`id`));
CREATE TABLE `message` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(500) NOT NULL,
`text` varchar(50000) NOT NULL,
`author_id` int(10) unsigned DEFAULT NULL,
`creation_date` datetime NOT NULL,
`last_update_date` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `author_id_fk` (`author_id`),
CONSTRAINT `message_ibfk_1` FOREIGN KEY (`author_id`) REFERENCES `author` (`id`));
CREATE TABLE `comment` (
`id` int(10) unsigned NOT NULL,
`post_id` int(10) unsigned NOT NULL,
KEY `message_id_fk` (`id`),
KEY `post_id_fk` (`post_id`),
CONSTRAINT `comment_ibfk_1` FOREIGN KEY (`id`) REFERENCES `message` (`id`),
CONSTRAINT `comment_ibfk_2` FOREIGN KEY (`post_id`) REFERENCES `post` (`id`));
CREATE TABLE `post` (
`id` int(10) unsigned NOT NULL,
KEY `message_id_fk` (`id`),
CONSTRAINT `post_ibfk_1` FOREIGN KEY (`id`) REFERENCES `message` (`id`) ON DELETE CASCADE);
And the following mapping with hibernate(3.5.4-Final):
#Entity
#Table(name = "author")
public class Author {
private Long id = 0L;
private String name;
private String email;
private String password;
private Set<Post> posts;
private Set<Comment> comments;
#Id
#Column(name = "id")
#GeneratedValue
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Column(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Column(name = "email")
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
#Column(name = "password")
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#OneToMany(mappedBy = "author")
public Set<Post> getPosts() {
return posts;
}
public void setPosts(Set<Post> posts) {
this.posts = posts;
}
#OneToMany(mappedBy = "author")
public Set<Comment> getComments() {
return comments;
}
public void setComments(Set<Comment> comments) {
this.comments = comments;
}
}
#MappedSuperclass
#Table(name = "message")
#Inheritance(strategy = InheritanceType.JOINED)
public abstract class Message implements Serializable {
private Long id;
private String title;
private String text;
private Author author;
private Date creationDate;
private Date lastUpdateDate;
#Id
#Column(name = "id")
#GeneratedValue
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Column(name = "title")
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
#Column(name = "text")
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
#ManyToOne
#JoinColumn(name = "author_id")
public Author getAuthor() {
return author;
}
public void setAuthor(Author author) {
this.author = author;
}
#Column(name = "creation_date")
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
#Column(name = "last_update_date")
public Date getLastUpdateDate() {
return lastUpdateDate;
}
public void setLastUpdateDate(Date lastUpdateDate) {
this.lastUpdateDate = lastUpdateDate;
}
}
#Entity
#Table(name = "comment")
#PrimaryKeyJoinColumn(name="id")
public class Comment extends Message {
private static final long serialVersionUID = 1L;
private Post post;
#ManyToOne
#JoinColumn(name = "post_id")
public Post getPost() {
return post;
}
public void setPost(Post post) {
this.post = post;
}
}
#Entity
#Table(name = "post")
#PrimaryKeyJoinColumn(name="id")
public class Post extends Message {
private static final long serialVersionUID = 1L;
private Set<Comment> comments;
#OneToMany(mappedBy = "post")
public Set<Comment> getComments() {
return comments;
}
public void setComments(Set<Comment> comments) {
this.comments = comments;
}
}
The main idea is that Comment and Post are inherited from Message and I would like both of them to have bidirectional relation. But when I run the following code:
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
Transaction tx = session.beginTransaction();
Author author = new Author();
author.setName("mike");
author.setPassword("123");
author.setEmail("mike#gmail.com");
Post post = new Post();
post.setAuthor(author);
post.setCreationDate(new Date());
post.setLastUpdateDate(new Date());
post.setText("Text");
post.setTitle("Title");
Long authorId = (Long)session.save(author);
Long postId = (Long)session.save(post);
tx.commit();
I get the following error:
ERROR JDBCExceptionReporter:101 - Unknown column 'author_id' in 'field list'
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not insert: [org.blogsample.mappingbeans.Post]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:92)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:64)
Update
As #JB Nizet mentioned before I changed #MappedSuperclass to #Entity, after that I've got another error mappedBy reference an unknown target entity property: org.blogsample.mappingbeans.Comment.author, this was solved by changing db structure(removed author_id from message table, added it to each of comment, post and created foreign keys for this column) and moving author(and getter/setter with mapping) to Comment, Post classes.
Your Message class shouldn't be annotated with #MappedSuperclass, but with #Entity. #MappedSuperclass means that entities extending this class inherit columns and associations from the super class, but these columns and associations go in the table of the subclass. author_id is not in the comment table or in the post table. It's in the message table.
Moreover #Table can only be used with an entity. Not with a mapped superclass, which is only used to inherit fields and associations, but is not mapped to its own table like an entity is.
I think your issue here is exactly the same as the one highlighted in this question.
Have a look at my answer there to see if that helps.