I am new to hibernate and postgres. Actually I am trying to map potgres database using Hibernate. This is my table stucture in postgresql
CREATE TABLE employee
(
id serial NOT NULL,
firstname character varying(20),
lastname character varying(20),
birth_date date,
cell_phone character varying(15),
CONSTRAINT employee_pkey PRIMARY KEY (id )
)
I am trying to add a record to the database using the following code
System.out.println("******* WRITE *******");
Employee empl = new Employee("Jack", "Bauer", new Date(System.currentTimeMillis()), "911");
empl = save(empl);
//This is the save function
private static Employee save(Employee employee) {
SessionFactory sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
session.beginTransaction();
int id = (Integer) session.save(employee);
employee.setId(id);
session.getTransaction().commit();
session.close();
return employee;
}
When I execute the code I am getting the following error
org.hibernate.HibernateException: Missing sequence or table: hibernate_sequence
Exception in thread "main" java.lang.ExceptionInInitializerError
at org.tcs.com.Hibernate.HibernateUtil.buildSessionFactory(HibernateUtil.java:18)
at org.tcs.com.Hibernate.HibernateUtil.<clinit>(HibernateUtil.java:8)
at org.tcs.com.Hibernate.MainApp.list(MainApp.java:51)
at org.tcs.com.Hibernate.MainApp.main(MainApp.java:17)
Caused by: org.hibernate.HibernateException: Missing sequence or table: hibernate_sequence
at org.hibernate.cfg.Configuration.validateSchema(Configuration.java:1282)
at org.hibernate.tool.hbm2ddl.SchemaValidator.validate(SchemaValidator.java:155)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:498)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1740)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1778)
at org.tcs.com.Hibernate.HibernateUtil.buildSessionFactory(HibernateUtil.java:15)
... 3 more
I have the sequence called "employee_id_seq" in my database. But I dont know why the database is looking for hibernate_seq. Could someone explain the error and the reason.
Thanks in advance!
Added info
This is my employee class
import java.sql.Date;
public class Employee {
private int id;
private String firstname;
private String lastname;
private Date birthDate;
private String cellphone;
public Employee() {
}
public Employee(String firstname, String lastname, Date birthdate, String phone) {
this.firstname = firstname;
this.lastname = lastname;
this.birthDate = birthdate;
this.cellphone = phone;
}
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 Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
public String getCellphone() {
return cellphone;
}
public void setCellphone(String cellphone) {
this.cellphone = cellphone;
}
}
In your domain or Model object annotate the id field as below and it should work. For me the GenerationType.AUTO failed
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
You haven't posted the important bit: the Employee class.
But my guess is that your Employee class is using #GeneratedValue() without specifying the sequence to use. So, Hibernate uses its default name: hibernate_sequence.
You can supply a sequence name as part of the GeneratedValue annotation. eg.
#GeneratedValue(strategy=SEQUENCE, generator="employee_id_seq")
Simple solution :
create hibernate_sequence table as :
"create sequence <schema>.hibernate_sequence"
If you encounter this with Spring Boot or Spring boot/Hibernate Migration then potentially you can try the following
Quote:
By default, Hibernate generates key from hibernate_sequence table, we
can disable it by setting this hibernate.use-new-id-generator-mappings
to false.
application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=mkyong
spring.datasource.password=password
spring.jpa.hibernate.use-new-id-generator-mappings=false
If you don't use annotation you should change YourClass.hbm.xml file.
Your ID section should be:
<id name="id" type="int" column="id">
<generator class="sequence">
<param name="sequence">employee_id_seq</param>
</generator>
</id>
File sample:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Employee" table="EMPLOYEE">
<meta attribute="class-description">
This class contains the employee detail.
</meta>
<id name="id" type="int" column="id">
<generator class="sequence">
<param name="sequence">employee_id_seq</param>
</generator>
</id>
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="salary" column="salary" type="int"/>
</class>
</hibernate-mapping>
You can do two things.
One is to just manually create a blank hibernate_sequence table postgresql.
Two, most likely there is a conflict with the user account permissions not allowing grails to create that table.
Apart from creating the table hibernate_sequence which has a column next_val
you can also set quarkus.hibernate-orm.database.generation = drop-and-create. Note this will delete all the record in you database.
For me, what was causing this error was the wrong version of the MySql.Data library.
I had a version 6.9.6.0 defined in the web.config and yet the actual referenced version was older.
I just commented out :
<system.data>
<DbProviderFactories>
<remove invariant="MySql.Data.MySqlClient" />
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.9.6.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
</DbProviderFactories>
</system.data>
Related
This is about as simple as it gets - A company (Company table) can have a PIA agreement (PIA table) but isn't required to have one. I have tried the entire day searching all over stack overflow and google with different wording and still cannot find a solution that works for SELECT, INSERT, AND UPDATE. I found some half-decent documentation on one-to-one vs many-to-one in Hibernate, but the examples are very vague. https://docs.jboss.org/hibernate/core/3.3/reference/en-US/html/mapping.html search this text "5.1.13. One-to-one"
create_company.sql
CREATE TABLE company (
id SMALLINT AUTO_INCREMENT,
name varchar(60) default NULL,
PRIMARY KEY (id)
);
create_pia.sql
CREATE TABLE pia (
company_id smallint,
agreement_number varchar(50),
PRIMARY KEY (company_id),
CONSTRAINT pia_ibfk_1 FOREIGN KEY (company_id) REFERENCES company (id)
);
Note: It seems cascade="all" was needed to get UPDATE to work.
When I use this:
<one-to-one name="pia" class="something.something.Pia" cascade="all"/>
SELECT and UPDATE both work, but INSERT Fails with this error:
java.sql.SQLException: Cannot add or update a child row: a foreign key constraint fails (`iti101088_15112`.`pia`, CONSTRAINT `pia_ibfk_1` FOREIGN KEY (`company_id`) REFERENCES `company` (`id`))
When I use this:
<many-to-one name="pia" class="something.something.Pia" cascade="all"/>
I get this when fetching the company:
Caused by: java.sql.SQLException: Unknown column 'company0_.pia' in 'field list'
When I use this:
<many-to-one name="pia" class="something.something.Pia" cascade="all" property-ref="companyId"/>
I get the same error when fetching the company:
Caused by: java.sql.SQLException: Unknown column 'company0_.pia' in 'field list'
When I use this:
<many-to-one name="pia" class="something.something.Pia" cascade="all" property-ref="companyId" column="id"/>
I get NullPointerException when fetching the company???????????
When I use the suggestion from here Hibernate doesn't support optional one-to-one (see HHH-2007) so you'll have to use a fake many-to-one with not-null="false" instead
Optional one-to-one mapping in Hibernate
<many-to-one name="pia" class="something.something.Pia" cascade="all" not-null="false"/>
I get this familiar error when fetching the company:
Caused by: java.sql.SQLException: Unknown column 'company0_.pia' in 'field list'
When I tweak it a little bit as such:
<many-to-one name="pia" class="something.something.Pia" cascade="all">
<column name="id" not-null="false"/>
</many-to-one>
I get this very strange error:
Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: could not initialize proxy [something.something.Pia#1] - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: could not initialize proxy [something.something.Pia#1] - no Session (through reference chain: something.something.Company["pia"]->something.something.Pia$HibernateProxy$54WqyDsD["agreementNumber"])
The code
Company.hbm.xml
<class name="something.something.Company" table="COMPANY">
<id name="id" column="ID">
<generator class="increment"/>
</id>
<property name="name" column="NAME"/>
<many-to-one name="pia" class="something.something.Pia" cascade="all"/>
</class>
Pia.hbm.xml
<class class="something.something.Pia" table="PIA">
<id name="companyId" column="COMPANY_ID"/>
<property name="agreementNumber" column="AGREEMENT_NUMBER"/>
</class>
Company.java
public class Company implements Serializable {
private static final long serialVersionUID = 1L;
private int id;
private String name;
public Company() { }
public Company(int id, String name, Pia pia) {
//I have no idea if this even does anything
super();
this.id = id;
this.name = name;
Pia companyPia = pia;
}
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 Pia getPia() { return pia; }
public void setPia(Pia pia) { this.pia = pia; }
}
Pia.java
public class Pia implements Serializable {
private int companyId;
private String agreementNumber;
public Pia() { }
public Pia(int companyId, String agreementNumber) {
this.companyId = companyId;
this.agreementNumber = agreementNumber;
}
public int getCompanyId() { return companyId; }
public void setCompanyId(int companyId) { this.companyId = companyId; }
public String getAgreementNumber() { return agreementNumber; }
public void setAgreementNumber(String agreementNumber) { this.agreementNumber = agreementNumber; }
}
SELECT statement execution java code:
#Override
public Company findCompanyByCompanyId(int companyId) {
return (Company) DataAccessUtils.singleResult(template.find("from Company where id=?0", companyId));
}
INSERT statement execution java code:
#Override
#Transactional
public int insertCompany(Company company) {
int result = -1;
try {
template.save(company);
result = company.getId();
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return result;
}
UPDATE statement execution java code:
#Override
#Transactional
public int updateCompany(Company myCompany) {
int result = 0;
try {
template.update(myCompany);
result = 1;
} catch (Exception e) {
logger.error(e.getMessage(), e);
result = -1;
}
return result;
}
Well, that's what you get when you read documentation for versions that are more than 15 years old. Here is the current documentation: https://docs.jboss.org/hibernate/orm/5.6/userguide/html_single/Hibernate_User_Guide.html#associations-one-to-one
Instead of googling and looking on stack overflow, try the official project website https://hibernate.org where you can find all the information you need. As for your model, it's pretty simple. This is all you need:
#Entity
public class Company {
#Id
private int id;
private String name;
#OneToOne(fetch = FetchType.LAZY, mappedBy = "company", cascade = CascadeType.ALL)
Pia pia;
}
#Entity
public class Pia {
#Id
#OneToOne(fetch = LAZY)
private Company company;
private String agreementNumber;
}
I have written few codes for inserting data into my SQL database. Actually, I am trying to learn Struts 2 with Hibernate. But, unfortunately I am facing a problem after submitting my form.
I could not find the reason for this error message. My try & catch block throws error like:
Exception in saveOrUpdate() Rollback :org.hibernate.MappingException: Unknown entity: v.esoft.pojos.Employee
Pojo(Employee.java):
#Entity
#Table(name = "employee", catalog = "eventusdb")
public class Employee implements java.io.Serializable {
private Integer empId;
private String name;
private String website;
public Employee() {
}
public Employee(String name, String website) {
this.name = name;
this.website = website;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "emp_id", unique = true, nullable = false)
public Integer getEmpId() {
return this.empId;
}
public void setEmpId(Integer empId) {
this.empId = empId;
}
#Column(name = "name", nullable = false)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
#Column(name = "website", nullable = false, length = 65535)
public String getWebsite() {
return this.website;
}
public void setWebsite(String website) {
this.website = website;
}
}
also having Employee.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Sep 10, 2013 4:29:04 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="v.esoft.pojos.Employee" table="employee" catalog="eventusdb">
<id name="empId" type="java.lang.Integer">
<column name="emp_id" />
<generator class="identity" />
</id>
<property name="name" type="string">
<column name="name" not-null="true" />
</property>
<property name="website" type="string">
<column name="website" length="65535" not-null="true" />
</property>
</class>
</hibernate-mapping>
If the entity isn't mapped, you should inspect the hibernate configuration. Hibernate is ORM framework used to map pojos (entities) to the database schema objects. You didn't configure or hibernate couldn't find mapping for the object Employee. The configuration file is hibernate.cfg.xml should contain the mapping to the resource Employee.hbm.xml. Suppose this file is in the same folder as Employee class. Then the mapping will be
<mapping resource="v/esoft/pojos/Employee.hbm.xml"/>
Another approach if you used an annotation based configuration, then you should use class attribute to map to the pojo that contains Hibernate/JPA annotations.
<mapping class="v.esoft.pojos.Employee"/>
Note, annotation based Configuration might be different depending on version of Hibernate and may require additional libraries.
Well, there are many questions exactly with this title but none of them have proper answers or they are not exactly the same as mine.
I have two entities:
Person:
#Entity
#Table(name = "Person")
#Inheritance(strategy = InheritanceType.JOINED)
#Access(AccessType.FIELD)
public class Person {
#Id
#GeneratedValue
private Long id;
#Column(name = "firstname")
private String firstName;
#Column(name = "lastname", length = 100, nullable = false, unique = false)
private String lastName;
#OneToMany(fetch=FetchType.LAZY, cascade=CascadeType.MERGE, mappedBy="owner")
private Set<Car> cars;
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 Set<Car> getCars() {
return cars;
}
public void setCars(Set<Car> cars) {
this.cars = cars;
}
#Override
public String toString() {
return String.format("(%d, %s, %s)",id, firstName, lastName);
}
}
And Car:
#Entity
#Table(name = "Car")
#Inheritance(strategy = InheritanceType.JOINED)
#Access(AccessType.FIELD)
public class Car {
#Id
#GeneratedValue
private Long id;
#ManyToOne(fetch=FetchType.LAZY, cascade=CascadeType.MERGE)
#JoinColumn(name="id_person", columnDefinition="BIGINT")
private Person owner;
#Column(name="name")
private String name;
#Column(name="model")
private String model;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Person getOwner() {
return owner;
}
public void setOwner(Person owner) {
this.owner = owner;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
#Override
public String toString() {
return String.format("(%d, %s, %s, %s)", id, name, model, owner);
}
}
Also I've defined a foreign key constraints in my Mysql database between Person and Car table on id_person column
My persistence.xml file is as followings:
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
<persistence-unit name="PersistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<!-- Configuring JDBC properties -->
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost/hibernatedb" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="DA_PASSWORD" />
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<!-- Hibernate properties -->
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
<property name="hibernate.hbm2ddl.auto" value="validate" />
<!-- Configuring Connection Pool -->
<property name="hibernate.c3p0.min_size" value="5" />
<property name="hibernate.c3p0.max_size" value="20" />
<property name="hibernate.c3p0.timeout" value="500" />
<property name="hibernate.c3p0.max_statements" value="50" />
<property name="hibernate.c3p0.idle_test_period" value="2000" />
</properties>
</persistence-unit>
</persistence>
Inside my code, I try to select Cars using Criteria query as following:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Car> q = cb.createQuery(Car.class);
Root<Car> root = q.from(Car.class);
q.select(root);
When I get the results and print them
TypedQuery<Car> typedQuery = entityManager.createQuery(q);
List<Car> cars = typedQuery.getResultList();
log.info("*****************************{}", cars);
To my surprise, It prints:
*****************************[(1, Hiundai, 2016, (1, Homer1530962140, Simpson)), (2, Benz, 2016, (1, Homer1530962140, Simpson)), (3, Benz,
2017, (2, Homer12935192, Simpson))]
That means for each car items, owners eagerly have been fetched too!
Here are the database query logs:
2017-02-17T14:02:58.324926Z 391 Query /* mysql-connector-java-5.1.13 ( Revision: ${bzr.revision-id} ) */SELECT ##session.auto_increment_increment
2017-02-17T14:02:58.325405Z 391 Query SHOW COLLATION
2017-02-17T14:02:58.335552Z 391 Query SET NAMES latin1
2017-02-17T14:02:58.335772Z 391 Query SET character_set_results = NULL
2017-02-17T14:02:58.336160Z 391 Query SET autocommit=1
2017-02-17T14:02:58.336349Z 391 Query SET autocommit=0
2017-02-17T14:02:58.720821Z 391 Query SHOW FULL TABLES FROM `hibernatedb` LIKE 'Car'
2017-02-17T14:02:58.724527Z 391 Query SHOW FULL TABLES FROM `hibernatedb` LIKE 'Car'
2017-02-17T14:02:58.725337Z 391 Query SHOW FULL COLUMNS FROM `Car` FROM `hibernatedb` LIKE '%'
2017-02-17T14:02:58.729899Z 391 Query SHOW FULL TABLES FROM `hibernatedb` LIKE 'Person'
2017-02-17T14:02:58.730468Z 391 Query SHOW FULL TABLES FROM `hibernatedb` LIKE 'Person'
2017-02-17T14:02:58.730887Z 391 Query SHOW FULL COLUMNS FROM `Person` FROM `hibernatedb` LIKE '%'
2017-02-17T14:02:59.022835Z 391 Query select car0_.id as id1_0_, car0_.model as model2_0_, car0_.name as name3_0_, car0_.id_person as id_perso4_0_ from Car car0_
2017-02-17T14:02:59.041016Z 391 Query SHOW WARNINGS
2017-02-17T14:02:59.045266Z 391 Query select person0_.id as id1_1_0_, person0_.firstname as firstnam2_1_0_, person0_.lastname as lastname3_1_0_ from Person person0_ where person0_.i
d=1
2017-02-17T14:02:59.059184Z 391 Query SHOW WARNINGS
2017-02-17T14:02:59.064163Z 391 Query select person0_.id as id1_1_0_, person0_.firstname as firstnam2_1_0_, person0_.lastname as lastname3_1_0_ from Person person0_ where person0_.i
d=2
2017-02-17T14:02:59.065827Z 391 Query SHOW WARNINGS
2017-02-17T14:02:59.070262Z 391 Query rollback
2017-02-17T14:02:59.070468Z 391 Quit
It is quite obvious that a separate query is issued to get Person information while I don't seem to ask such a thing in my code.
Why is this happening?
You requested the owner information when you converted the car to a string.
#Override
public String toString() {
return String.format("(%d, %s, %s, %s)", id, name, model, owner);
}
At that point, it had to retrieve the owner to execute your toString().
log.info("*****************************{}", cars);
When you execute this:
Logging framework calls toString() on a list
toString() is called on each Car
toString method of the Car class calls toString() method of the Person class. And this is the part where "magic" happens. Turns out that Hibernate uses generated proxy classes to enable lazy loading for some associations (one-to-one, many-to-one). In other words, Hibernate initializes field Car.owner with a reference to a proxy class that extends the Person class. This proxy class contains additional logic that handles lazy loading.
I have two tables and want to map them to one object with Hibernate.
The reason for both tables is in the past and I wont change the frontend, which access data like this.
I have Table Event (Event_ID, Preview, img) and Event_Details (ID, Event_ID, content).
I prepare one class in Java:
public class Event {
private int event_ID;
private String preview;
private String img;
private String content;
//Getter and Setter
}
and following XML mapping file:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 16.03.2016 20:33:10 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="de.data.events.Event" table="ev1_event">
<id name="id" type="int">
<column name="Event_ID" />
<generator class="assigned" />
</id>
<property name="preview" type="java.lang.String">
<column name="ev1_preview" />
</property>
<property name="img" type="java.lang.String">
<column name="ev1_img" />
</property>
</class>
<class name="de.data.events.Event" table="pb1_event">
<id name="id" type="int">
<column name="id" />
<generator class="assigned" />
</id>
//some properties
</class>
The part, where I have to join table1 to table2 is missing. But I didnĀ“t found a way to fix my problem.
First, you'd have your Hibernate entities. Yours are Event and EventDetail, but for fun, let's go with Person and Address in this example. The key here is that you need a one-to-one or many-to-one relationship between your tables. Otherwise, your resultset will come out weird (more on that later).
#Entity
#Table(name = "PERSON")
public class Person {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "PERSON_ID")
public Integer id;
#Column(name = "NAME")
public String name;
#Column(name = "HOME_ADDRESS_ID")
public Integer homeAddressId;
#Column(name = "TEMP_ADDRESS_ID")
public Integer tempAddressId;
// . . . other fields,getters,setters
}
#Entity
#Table(name = "ADDRESS")
public class Address {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ADDRESS_ID")
public Integer id;
#Column(name = "STREET")
public String street;
#Column(name = "CITY")
public String city;
// . . . other fields,getters,setters
}
Then you'd have your target FlatObject POJO with the a constructor that will build it appropriately:
public class FlatObject {
public final String name;
public final String homeStreet;
public final String homeCity;
public final String tempStreet;
public final String tempCity;
public FlatEntity(String name, String homeStreet, String homeCity, String tempStreet, String tempCity) {
this.name = name;
this.homeStreet = homeStreet;
this.homeCity = homeCity;
this.tempStreet = tempStreet;
this.tempCity = tempCity;
}
// . . . other fields,getters
}
Finally, you'd leverage those objects with a Hibernate HQL SELECT where you join Person and Address and use their fields to construct a new FlatEntity:
SELECT new FlatEntity(p.name, ha.homeStreet, ha.homeCity, ta.tempStreet, ta.tempCity)
FROM
Person p, Address ha, Address ta
WHERE
p.homeAddressId = ha.id
and p.tempAddressId = ta.id
As you can see, the HQL statment will join Person to Address twice: once for the home address and once for the temp address.
The same will hold true in your case. So in your case, if you're joining Event e, EventDetail ed WHERE e.id = ed.eventId, just be sure there's only one detail row per Event. Otherwise you'll get multiple rows when you have more than one details or you'll drop rows (because of the inner join) when an event has no details.
There is a mapping exception for a particular entity.
Cant figure out from where the problem is arising.
I checked all the mappings 3 times from start to end.
Still i am getting a Mapping Exception.
Email to employee is mapped only once.
but still it is reporting the error repeated mapping
Error is:
Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: com.cluster.entity.Email column: EMPLOYEE_ID (should be mapped with insert="false" update="false")
at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:680)
at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:702)
at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:724)
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:477)
at org.hibernate.mapping.RootClass.validate(RootClass.java:268)
at org.hibernate.cfg.Configuration.validate(Configuration.java:1287)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1729)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1775)
at com.cluster.util.HibernateUtil.<clinit>(HibernateUtil.java:16)
... 1 more
Email Pojo
package com.cluster.entity;
public class Email {
private int intEmailID;
private String strEmailName;
//many to one
private EmailType emailType;
//many to one
private Employee employee;
public int getIntEmailID() {
return intEmailID;
}
public void setIntEmailID(int intEmailID) {
this.intEmailID = intEmailID;
}
public String getStrEmailName() {
return strEmailName;
}
public void setStrEmailName(String strEmailName) {
this.strEmailName = strEmailName;
}
public EmailType getEmailType() {
return emailType;
}
public void setEmailType(EmailType emailType) {
this.emailType = emailType;
}
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
}
email.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
'-//Hibernate/Hibernate Mapping DTD 3.0//EN'
'http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd'>
<hibernate-mapping package="com.cluster.entity" >
<class name="Email" table="EMAIL">
<id name="intEmailID" column="EMAIL_ID">
<generator class="sequence">
<param name="sequence">EMAIL_ID_SEQ</param>
</generator>
</id>
<property name="strEmailName" column = "EMAIL_NAME"/>
<many-to-one name="employee" column="EMPLOYEE_ID" not-null = "true" class = "Employee"/>
<many-to-one name="emailType" column="EMAIL_TYPE_ID" not-null = "true" class = "EmailType"/>
</class>
</hibernate-mapping>
Related Script
CREATE TABLE EMPLOYEE
(
EMPLOYEE_ID NUMBER NOT NULL,
FIRSTNAME VARCHAR2(20 BYTE) NOT NULL,
LASTNAME VARCHAR2(20 BYTE) NOT NULL,
DATE_OF_BIRTH VARCHAR2(20 BYTE) NOT NULL,
SALARY VARCHAR2(10 BYTE) NOT NULL,
DEPARTMENT_ID NUMBER NOT NULL
);
CREATE TABLE EMAIL
(
EMAIL_ID NUMBER NOT NULL,
EMAIL_NAME VARCHAR2(40 BYTE) NOT NULL,
EMPLOYEE_ID NUMBER NOT NULL,
EMAIL_TYPE_ID NUMBER NOT NULL
);
CREATE TABLE EMAIL_TYPE
(
EMAIL_TYPE_ID NUMBER NOT NULL,
EMAIL_TYPE_NAME VARCHAR2(40 BYTE) NOT NULL
);
ALTER TABLE EMPLOYEE ADD
(
CONSTRAINT PK_EMPLOYEE_ID
PRIMARY KEY (EMPLOYEE_ID)
);
ALTER TABLE EMAIL_TYPE ADD
(
CONSTRAINT PK_EMAIL_TYPE_ID
PRIMARY KEY (EMAIL_TYPE_ID)
);
ALTER TABLE EMAIL ADD
(
CONSTRAINT PK_EMAIL_ID
PRIMARY KEY (EMAIL_ID)
);
ALTER TABLE EMAIL ADD
(
CONSTRAINT FK_EMAIL_EMPLOYEE_ID
FOREIGN KEY (EMPLOYEE_ID)
REFERENCES EMPLOYEE (EMPLOYEE_ID)
);
ALTER TABLE EMAIL ADD
(
CONSTRAINT FK_EMAIL_EMAIL_TYPE_ID
FOREIGN KEY (EMAIL_TYPE_ID)
REFERENCES EMAIL_TYPE (EMAIL_TYPE_ID)
);
Email to employee is mapped only once.
but still it is reporting the error repeated mapping
have you set the collection in Employee as inverse?
<bag name="emails" inverse="true">
<key column="EMPLOYEE_ID" not-null="true">
...
</bag>
For those who are using annotations to solve this, the classes should look like this:
#Entity
public class Email {
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE)
private int intEmailID;
#Column(insertable = false, updatable = false)
private int employeeId;
#ManyToOne
private EmailType emailType;
#ManyToOne
#JoinColumn(name="employeeId")
private Employee employee;
// Getters and Setter
}
#Entity
public class Employee {
#Id
private int id;
#OneToMany(cascade = {CascadeType.ALL}, mappedBy="employeeId")
#PrimaryKeyJoinColumn
private List<Email> emailList;
public void setEmailList(List<Email> emailList) {
this.emailList = emailList
}
public List<Email> getEmailList() {
return emailList;
}
// Rest of getters and setters
}
I think you have mapped Employee to Email using oneToMany relation. If yes its nothing wrong but you have to make sure you can insert and update only in one direction
should be mapped with insert="false" update="false" in Employee