I want to create list of embedded objects with Hibernate and MySql.
But I cought bunch of errors:
Hibernate: alter table USERS drop foreign key FK_qymdwjo8d0eu0lhfd3ngfs74d
2014-07-09 15:40:47 ERROR SchemaExport:425 - HHH000389: Unsuccessful: alter table USERS drop foreign key FK_qymdwjo8d0eu0lhfd3ngfs74d
2014-07-09 15:40:47 ERROR SchemaExport:426 - Can't DROP 'FK_qymdwjo8d0eu0lhfd3ngfs74d'; check that column/key exists
Hibernate: drop table if exists USERS
2014-07-09 15:40:48 ERROR SchemaExport:425 - HHH000389: Unsuccessful: drop table if exists USERS
2014-07-09 15:40:48 ERROR SchemaExport:426 - Cannot delete or update a parent row: a foreign key constraint fails
Hibernate: drop table if exists hibernate_unique_key
Hibernate: create table USERS (id integer not null, city varchar(35), pincode varchar(35), state varchar(35), street varchar(35), description varchar(35), joinedDate date, name varchar(35), ADDRESSES_ID bigint not null, primary key (ADDRESSES_ID))
2014-07-09 15:40:48 ERROR SchemaExport:425 - HHH000389: Unsuccessful: create table USERS (id integer not null, city varchar(35), pincode varchar(35), state varchar(35), street varchar(35), description varchar(35), joinedDate date, name varchar(35), ADDRESSES_ID bigint not null, primary key (ADDRESSES_ID))
2014-07-09 15:40:48 ERROR SchemaExport:426 - Table 'users' already exists
Hibernate: alter table USERS add constraint FK_qymdwjo8d0eu0lhfd3ngfs74d foreign key (id) references USERS (ADDRESSES_ID)
2014-07-09 15:40:48 ERROR SchemaExport:425 - HHH000389: Unsuccessful: alter table USERS add constraint FK_qymdwjo8d0eu0lhfd3ngfs74d foreign key (id) references USERS (ADDRESSES_ID)
2014-07-09 15:40:48 ERROR SchemaExport:426 - Cannot add foreign key constraint
Hibernate: create table hibernate_unique_key ( next_hi integer )
Hibernate: insert into hibernate_unique_key values ( 0 )
2014-07-09 15:40:48 INFO SchemaExport:405 - HHH000230: Schema export complete
Hibernate: insert into USERS (city, pincode, state, street, description, joinedDate, name) values (?, ?, ?, ?, ?, ?, ?)
Hibernate: select next_hi from hibernate_unique_key for update
Hibernate: update hibernate_unique_key set next_hi = ? where next_hi = ?
Hibernate: insert into USERS (id, ADDRESSES_ID, city, pincode, state, street) values (?, ?, ?, ?, ?, ?)
2014-07-09 15:40:48 WARN SqlExceptionHelper:144 - SQL Error: 1054, SQLState: 42S22
2014-07-09 15:40:48 ERROR SqlExceptionHelper:146 - Unknown column 'ADDRESSES_ID' in 'field list'
2014-07-09 15:40:48 INFO AbstractBatchImpl:208 - HHH000010: On release of batch it still contained JDBC statements
org.hibernate.exception.SQLGrammarException: could not execute statement
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:80)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:190)
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:62)
at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1311)
at org.hibernate.action.internal.CollectionRecreateAction.execute(CollectionRecreateAction.java:67)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:463)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:349)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:350)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1222)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177)
at com.demo.hibernate.HibernateDemo.createUser(HibernateDemo.java:59)
at com.demo.hibernate.HibernateDemo.main(HibernateDemo.java:37)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'ADDRESSES_ID' in 'field list'
Here is main():
public static void main(String[] args) {
try {
HibernateDemo demo = new HibernateDemo();
UserDetails user = new UserDetails();
Address address = new Address();
address.setStreet("Name");
address.setCity("Kiev");
address.setPincode("00000");
address.setState("My state");
Address addr = new Address();
addr.setStreet("new name");
addr.setCity("Lviv");
addr.setPincode("79040");
addr.setState("state");
user.getListOfAddresses().add(address);
user.getListOfAddresses().add(addr);
user.setUserName("Carl");
user.setJoinedDate(new Date());
user.setDescription("it is cool guy");
user.setAddress(address);
demo.createUser(user);
demo.listUsers();
user.setUserName("Bruno Shults");
demo.updateUser(user);
demo.listUsers();
} catch (Exception e) {
e.printStackTrace();
} finally {
System.runFinalizersOnExit(true);
System.exit(1);
}
UserDetails class:
#Entity
#Table(name = "USERS")
public class UserDetails {
#Id
#GeneratedValue
#Column(name = "id")
private int userId;
#Column(name = "name", length = 35)
private String userName;
#Temporal(TemporalType.DATE)
private Date joinedDate;
#Column(length = 35)
private Address address;
#Column(length = 35)
private String description;
#ElementCollection
#JoinTable(name = "USERS", joinColumns = #JoinColumn(name = "id"))
#GenericGenerator(name = "hilo-gen", strategy = "hilo")
#CollectionId(columns = {#Column(name = "ADDRESSES_ID")}, generator = "hilo-gen", type = #Type(type = "long"))
private Collection<Address> listOfAddresses = new ArrayList<Address>();
// getters and setters
Address class:
#Embeddable
public class Address {
#Column(length = 35)
private String street;
#Column(length = 35)
private String city;
#Column(length = 35)
private String state;
#Column(length = 35)
private String pincode;
// getters and setters
cfg xml file:
<hibernate-configuration>
<session-factory>
<!--Database connection settings-->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost/hibernatedb</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">secret</property>
<!--JDBC connection pool-->
<property name="hibernate.connection.pool_size">2</property>
<!--SQL dialect-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!--Disable the second level cache-->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCachingRegionFactory</property>
<!--Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!--Drop and recreate the database schema on startup-->
<property name="hbm2ddl.auto">create</property>
<!--<property name="hbm2ddl.auto">update</property>-->
<!-- List of XML mapping files -->
<mapping class="com.demo.dto.UserDetails"/>
Here is DB struckture looking:
and diagram:
I couldn't figure out why it creates hibernate_unique_key table? It shouldn't.
Any suggestions?
well these lines
Hibernate: create table hibernate_unique_key ( next_hi integer )
Hibernate: insert into hibernate_unique_key values ( 0 )
appear because of
#GenericGenerator(name = "hilo-gen", strategy = "hilo")
in your address
hilo: Generates a Integer, long or short type of ids. This uses a High – Low algorithm. As the name suggests, it depends upon the highest table id and then reads the possible lowest available value.
Read more about it here
Related
Industry_Codes Table
Industry_Code(Primary key) | Industry_name
1| Reliance
2| TaTa
Technology_codes Table
Technology_code(Primary Key) | technology name
81| java
81|cpp
carrier_codes Table
Industry_Code(Primary key)(Foreign Key to Industry_Codes table) | technology_code(pk)(Foreign key to Technology_Code table) | other fields
1 | 81 |
2| 81|
1| 82
Register
Mobile Number(Pk)|Industry_code(Fk to carrier_codes) |Technology_Code(Fk to carrier_codes)
12345|1|83
78913|1|88
for the given table structure the entity class are written as-
#Entity
#Table(name = "Industry_Codes")
public class IndustryCodes implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name="TELECOM_INDUSTRY_CODE")
private String telecomIndustryCode;
#Column(name="INdustry_Name")
private String Industry_Name;
}
Table 2
#Entity
#Table(name="Technology_Codes")
public class TechnologyCodes {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "Technology_code")
private int targetTechnologyCode;
#Column(name="Technology_Name")
private String TechnologyName;
}
and
#Entity
#Table(name = "CARRIER_CODES")
public class CarrierCodes {
private static final long serialVersionUID = 1L;
#Id
#ManyToOne
#JoinColumn(name ="CARRIER_CODE",referencedColumnName="INDUSTRY_CODE")
private IndustryCodes carrierCode;
#Id
#ManyToOne
#JoinColumn(name ="TECHNOLOGY_CODE",referencedColumnName="TECHNOLOGY_CODE")
private TechnologyCodes TechnologyCode;
}
Now I am all lost on how to write entity for Register table which has column like carrier_code and technology_code both of these are foreign key to carrier_codes table adn both of these together form composite key for carrier_codes table also there are many occurance of both field in both table thus a many to many association between both columns of both table.
Any help on writing the register entity is appreciated. I am completely new to associations in JPA.
First, be sure you understand the relationships. UML and images are your friend.
Notice that IndustryCode and TechCode is a ManyToMany relationship. In DDL a many to many relationship is done with join table and a composite key. In JPA this is normally just mapped with a ManyToMany annotation but since you also want to use it as a foreign key for the Registry table you must define the entity yourself. This is done with CarrierCodes. In JPA an EmbeddableId is generally the easiest way to make a composite key for an entity that will be used in this manner. So the JPA can be done like this:
#Entity
public class IndustryCode {
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
private String industryName;
#OneToMany(mappedBy="industryCode")
private Set<CarrierCodes> industryCodes;
#Entity
public class TechCode {
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
private String techName;
#OneToMany(mappedBy="techCode")
private Set<CarrierCodes> techCodes;
#Entity
public class CarrierCodes {
#EmbeddedId
private CarrierCodesId id = new CarrierCodesId();
#ManyToOne
#MapsId("techCodeId")
private TechCode techCode;
#ManyToOne
#MapsId("industryCodeId")
private IndustryCode industryCode;
#SuppressWarnings("serial")
#Embeddable
public class CarrierCodesId implements Serializable {
private Long industryCodeId;
private Long techCodeId;
#Entity
public class Register {
#Id
private Long mobileNumber;
#ManyToOne
// optional but nice to have consistent names
#JoinColumns({
#JoinColumn(name="industryCode_id", referencedColumnName="industryCode_id"),
#JoinColumn(name="techCode_id", referencedColumnName="techCode_id")
})
private CarrierCodes carrierCodes;
And to use it similar to your example is like this.
tx.begin();
IndustryCode ic1 = new IndustryCode("Reliance");
IndustryCode ic2 = new IndustryCode("TaTa");
TechCode tc1 = new TechCode("java");
TechCode tc2 = new TechCode("cpp");
CarrierCodes cc1 = new CarrierCodes(tc1, ic1);
CarrierCodes cc2 = new CarrierCodes(tc1, ic2);
CarrierCodes cc3 = new CarrierCodes(tc2, ic1);
Register r1 = new Register(12345L, cc1);
Register r2 = new Register(78913L, cc2);
em.persist(ic1);
em.persist(ic2);
em.persist(tc1);
em.persist(tc2);
em.persist(cc1);
em.persist(cc2);
em.persist(cc3);
em.persist(r1);
em.persist(r2);
tx.commit();
em.clear();
List<Register> rs = em.createQuery("select r from Register r left outer join fetch r.carrierCodes cc where cc.techCode.techName = 'java'", Register.class).getResultList();
rs.stream().forEach(r->System.out.println(r.getMobileNumber() + " " + r.getCarrierCodes().getTechCode().getTechName()));
List<Register> rs2 = em.createQuery("select r from Register r left outer join fetch r.carrierCodes cc where cc.industryCode.industryName = 'TaTa'", Register.class).getResultList();
rs2.stream().forEach(r->System.out.println(r.getMobileNumber() + " " + r.getCarrierCodes().getIndustryCode().getIndustryName()));
That gives me the following output.
Hibernate: create table CarrierCodes (industryCode_id bigint not null, techCode_id bigint not null, primary key (industryCode_id, techCode_id))
Hibernate: create table IndustryCode (id bigint generated by default as identity (start with 1), industryName varchar(255), primary key (id))
Hibernate: create table Register (mobileNumber bigint not null, industryCode_id bigint, techCode_id bigint, primary key (mobileNumber))
Hibernate: create table TechCode (id bigint generated by default as identity (start with 1), techName varchar(255), primary key (id))
Hibernate: alter table CarrierCodes add constraint FKfq42ix66txvd15crq2pey3dcp foreign key (industryCode_id) references IndustryCode
Hibernate: alter table CarrierCodes add constraint FK9os97pd53ijerp2mibllknovn foreign key (techCode_id) references TechCode
Hibernate: alter table Register add constraint FK2k626ouo1ajsccqlpb5y3xa8u foreign key (industryCode_id, techCode_id) references CarrierCodes
Hibernate: insert into IndustryCode (id, industryName) values (default, ?)
Hibernate: insert into IndustryCode (id, industryName) values (default, ?)
Hibernate: insert into TechCode (id, techName) values (default, ?)
Hibernate: insert into TechCode (id, techName) values (default, ?)
Hibernate: insert into CarrierCodes (industryCode_id, techCode_id) values (?, ?)
Hibernate: insert into CarrierCodes (industryCode_id, techCode_id) values (?, ?)
Hibernate: insert into CarrierCodes (industryCode_id, techCode_id) values (?, ?)
Hibernate: insert into Register (industryCode_id, techCode_id, mobileNumber) values (?, ?, ?)
Hibernate: insert into Register (industryCode_id, techCode_id, mobileNumber) values (?, ?, ?)
Hibernate: select register0_.mobileNumber as mobileNu1_2_0_, carriercod1_.industryCode_id as industry1_0_1_, carriercod1_.techCode_id as techCode2_0_1_, register0_.industryCode_id as industry2_2_0_, register0_.techCode_id as techCode3_2_0_ from Register register0_ left outer join CarrierCodes carriercod1_ on register0_.industryCode_id=carriercod1_.industryCode_id and register0_.techCode_id=carriercod1_.techCode_id cross join TechCode techcode2_ where carriercod1_.techCode_id=techcode2_.id and techcode2_.techName='java'
Hibernate: select industryco0_.id as id1_1_0_, industryco0_.industryName as industry2_1_0_ from IndustryCode industryco0_ where industryco0_.id=?
Hibernate: select techcode0_.id as id1_3_0_, techcode0_.techName as techName2_3_0_ from TechCode techcode0_ where techcode0_.id=?
Hibernate: select industryco0_.id as id1_1_0_, industryco0_.industryName as industry2_1_0_ from IndustryCode industryco0_ where industryco0_.id=?
12345 java
78913 java
Hibernate: select register0_.mobileNumber as mobileNu1_2_0_, carriercod1_.industryCode_id as industry1_0_1_, carriercod1_.techCode_id as techCode2_0_1_, register0_.industryCode_id as industry2_2_0_, register0_.techCode_id as techCode3_2_0_ from Register register0_ left outer join CarrierCodes carriercod1_ on register0_.industryCode_id=carriercod1_.industryCode_id and register0_.techCode_id=carriercod1_.techCode_id cross join IndustryCode industryco2_ where carriercod1_.industryCode_id=industryco2_.id and industryco2_.industryName='TaTa'
78913 TaTa
While learning JPA/Hibernate I stumbbled upon something unexpected. I am getting an unnecessary double select query to the db (see buttom).I have a simple OneToOne setup.
This is my Contact entity:
#Entity
#Table(name = "contact")
public class Contact {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "contact_id", nullable = false, insertable = false, updatable = false)
private Long id;
#Column(name = "name", nullable = false)
private String name;
#OneToOne
#JoinColumn(name="fk_address_id", referencedColumnName="address_id")
private Address address;
public Contact(String name, Address address) {
this.name = name;
this.address = address;
}
// getters/setters
}
My Address entity:
#Entity
#Table(name = "address")
public class Address {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "address_id", nullable = false, insertable = false, updatable = false)
private Long id;
#Column(name = "location", nullable = false)
private String location;
#OneToOne(mappedBy = "address")
private Contact contact;
public Address(String location) {
this.location = location;
}
// getters/setters
}
This is how I ran my code:
private EntityManager em;
#Before
public void setup() {
em = EntityManagerFactoryCreator.getEntityManagerFactory().createEntityManager();
}
#Test
public void createContactWithAddress() {
Address address = new Address("Made");
Contact contact = new Contact("Jan", address);
em.getTransaction().begin();
em.persist(address);
em.persist(contact);
em.getTransaction().commit();
em.close();
em = EntityManagerFactoryCreator.getEntityManagerFactory().createEntityManager();
Contact managedContact = em.find(Contact.class, 1L);
}
}
It is probably something stupid, but what is causing the double select?
Hibernate:
drop table address if exists
Hibernate:
drop table book if exists
Hibernate:
drop table contact if exists
Hibernate:
create table address (
address_id bigint generated by default as identity,
location varchar(255) not null,
primary key (address_id)
)
Hibernate:
create table book (
book_id bigint generated by default as identity,
category varchar(255),
release_date date,
summary varchar(255),
title varchar(255) not null,
primary key (book_id)
)
Hibernate:
create table contact (
contact_id bigint generated by default as identity,
name varchar(255) not null,
address_address_id bigint,
primary key (contact_id)
)
Hibernate:
alter table book
add constraint UK_g0286ag1dlt4473st1ugemd0m unique (title)
Hibernate:
alter table contact
add constraint FKrc0ixa9b11b9tv3hyq0iwvdpt
foreign key (address_address_id)
references address
Hibernate:
insert
into
address
(address_id, location)
values
(null, ?)
TRACE o.h.t.d.s.BasicBinder [main]: binding parameter [1] as [VARCHAR] - [Made]
Hibernate:
insert
into
contact
(contact_id, address_address_id, name)
values
(null, ?, ?)
TRACE o.h.t.d.s.BasicBinder [main]: binding parameter [1] as [BIGINT] - [1]
TRACE o.h.t.d.s.BasicBinder [main]: binding parameter [2] as [VARCHAR] - [Jan]
Hibernate:
select
contact0_.contact_id as contact_1_2_0_,
contact0_.address_address_id as address_3_2_0_,
contact0_.name as name2_2_0_,
address1_.address_id as address_1_0_1_,
address1_.location as location2_0_1_
from
contact contact0_
left outer join
address address1_
on contact0_.address_address_id=address1_.address_id
where
contact0_.contact_id=?
TRACE o.h.t.d.s.BasicBinder [main]: binding parameter [1] as [BIGINT] - [1]
TRACE o.h.t.d.s.BasicExtractor [main]: extracted value ([address_1_0_1_] : [BIGINT]) - [1]
TRACE o.h.t.d.s.BasicExtractor [main]: extracted value ([address_3_2_0_] : [BIGINT]) - [1]
TRACE o.h.t.d.s.BasicExtractor [main]: extracted value ([name2_2_0_] : [VARCHAR]) - [Jan]
TRACE o.h.t.d.s.BasicExtractor [main]: extracted value ([location2_0_1_] : [VARCHAR]) - [Made]
Hibernate:
select
contact0_.contact_id as contact_1_2_1_,
contact0_.address_address_id as address_3_2_1_,
contact0_.name as name2_2_1_,
address1_.address_id as address_1_0_0_,
address1_.location as location2_0_0_
from
contact contact0_
left outer join
address address1_
on contact0_.address_address_id=address1_.address_id
where
contact0_.address_address_id=?
TRACE o.h.t.d.s.BasicBinder [main]: binding parameter [1] as [BIGINT] - [1]
TRACE o.h.t.d.s.BasicExtractor [main]: extracted value ([address_1_0_0_] : [BIGINT]) - [1]
TRACE o.h.t.d.s.BasicExtractor [main]: extracted value ([contact_1_2_1_] : [BIGINT]) - [1]
Note:
My EntityManagerFactoryCreator is a singleton that calls
Persistence.createEntityManagerFactory("nl.infosupport.javaminor.week4.jpa.h2");
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="nl.infosupport.javaminor.week4.jpa.h2">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="javax.persistence.jdbc.user" value="sa"/>
<property name="javax.persistence.jdbc.password" value="sa"/>
<property name="javax.persistence.jdbc.url" value="jdbc:h2:~/Documents/InfoSupport-Minor/h2_embedded_db/test"/>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
</properties>
</persistence-unit>
</persistence>
This is normal behavior in this case and with the tables config you have. If you want to have just one select, you need to use a custom query joining the child table. For example, using HQL it would look like that:
public Contact find(Long id) {
TypedQuery<Contact> query = em.createQuery(
"SELECT c FROM Contact c join fetch c.address WHERE c.id = :id", Contact.class);
return query
.setParameter("id", id)
.getSingleResult();
}
The code is not necessary working, I didn't debug it, but it shows the principle.
UPDATED
Or you can try annotating the field like
#Fetch(FetchMode.JOIN)
private Address address;
And then it will fire just one query.
I have 2 entities like below:
#Entity
public class Driver {
#Id
#GeneratedValue
private Integer id;
private String name;
#OneToMany
private List<Car> cars = new ArrayList<Car>();
public List<Car> getCars() {
return cars;
}
public void setCars(List<Car> cars) {
this.cars = cars;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
#Entity
public class Car {
#Id
#GeneratedValue
#Column(name="car_id")
private Integer carId;
#Column(name="car_type")
private String carType;
public Integer getCarId() {
return carId;
}
public void setCarId(Integer carId) {
this.carId = carId;
}
public String getCarType() {
return carType;
}
public void setCarType(String carType) {
this.carType = carType;
}
}
Hibernate configuration is like below:
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- SQL Dialect -->
<property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
<!-- Data base setting -->
<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="hibernate.connection.username">hibernate</property>
<property name="hibernate.connection.password">hibernate</property>
<property name="hibernate.connection.url">jdbc:oracle:thin:#localhost:1521:orcl</property>
<property name="show_sql">true</property>
<property name="hibernate.hbm2ddl.auto">create</property>
<mapping class="org.dxc.hibernate.one.to.many.Driver"/>
<mapping class="org.dxc.hibernate.one.to.many.Car"/>
</session-factory>
</hibernate-configuration>
then I wrote following code to insert data into DB:
private static void test1()
{
Driver driver = new Driver();
driver.setName("Bitt");
Car car1 = new Car();
car1.setCarType("SUV");
Car car2 = new Car();
car2.setCarType("Jeep");
Session session = getSessionFactory().openSession();
session.beginTransaction();
session.save(driver);
session.save(car1);
session.save(car2);
session.getTransaction().commit();
session.close();
}
but I go to Oracle just see data in Driver and Car table, but Driver_Car table is empty, I don't know what happened.
the output content in the eclipse console is like below:
INFO: HHH000400: Using dialect: org.hibernate.dialect.Oracle10gDialect
Hibernate: drop table Car cascade constraints
Jun 22, 2017 9:51:12 AM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess#40499e4f] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
Hibernate: drop table Driver cascade constraints
Hibernate: drop table Driver_Car cascade constraints
Hibernate: drop sequence hibernate_sequence
Hibernate: create sequence hibernate_sequence start with 1 increment by 1
Jun 22, 2017 9:51:12 AM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess#6b9ce1bf] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
Hibernate: create table Car (car_id number(10,0) not null, car_type varchar2(255 char), primary key (car_id))
Hibernate: create table Driver (id number(10,0) not null, name varchar2(255 char), primary key (id))
Hibernate: create table Driver_Car (Driver_id number(10,0) not null, cars_car_id number(10,0) not null)
Hibernate: alter table Driver_Car add constraint UK_esk5nfu72tp8wnrnvgudvsel5 unique (cars_car_id)
Hibernate: alter table Driver_Car add constraint FKskkihgsvn6a35dqroow0yrx3m foreign key (cars_car_id) references Car
Hibernate: alter table Driver_Car add constraint FK9yujoqc8mcau9bvembcfp8kto foreign key (Driver_id) references Driver
Jun 22, 2017 9:51:12 AM org.hibernate.tool.schema.internal.SchemaCreatorImpl applyImportSources
INFO: HHH000476: Executing import script 'org.hibernate.tool.schema.internal.exec.ScriptSourceInputNonExistentImpl#4fc5e095'
Hibernate: select hibernate_sequence.nextval from dual
Hibernate: select hibernate_sequence.nextval from dual
Hibernate: select hibernate_sequence.nextval from dual
Hibernate: insert into Driver (name, id) values (?, ?)
Hibernate: insert into Car (car_type, car_id) values (?, ?)
Hibernate: insert into Car (car_type, car_id) values (?, ?)
Can someone help me?
I have two simple tables Customers and Orders with relation oneToMany from customer to Orders table.
This is my Customers.java
#Entity
public class Customers implements Serializable {
#Id
#GeneratedValue
private int cID;
private String name;
private String email;
// getter and setters
}
And this is Orders.java:
#Entity
public class Orders implements Serializable {
#Id
#GeneratedValue
private int orderID;
private int cId;
#Column(nullable = false)
#Temporal(TemporalType.DATE)
private Date date;
#ManyToOne(cascade = CascadeType.ALL)
private Customers customers;
// getter and setters
}
Now, i am going to insert two record in Orders table:
public static void main(String[] args) {
SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
Orders orders1 = new Orders();
Orders orders2 = new Orders();
Customers customer = new Customers();
customer.setName("c1");
customer.setEmail("abc#gmail.com");
orders1.setDate(new Date());
orders2.setDate(new Date());
orders1.setCustomers(customer);
orders2.setCustomers(customer);
session.save(orders1);
session.save(orders2);
session.getTransaction().commit();
session.close();
sessionFactory.close();
}
This is the result in console:
Hibernate: alter table Orders drop foreign key FK_hmbx2rg9tsgqikb3kodqp90c4
Hibernate: drop table if exists Customers
Hibernate: drop table if exists Orders
Hibernate: create table Customers (cID integer not null auto_increment, email varchar(255), name varchar(255), primary key (cID))
Hibernate: create table Orders (orderID integer not null auto_increment, cId integer not null, date date not null, customers_cID integer, primary key (orderID))
Hibernate: alter table Orders add constraint FK_hmbx2rg9tsgqikb3kodqp90c4 foreign key (customers_cID) references Customers (cID)
Feb 24, 2015 1:58:52 PM org.hibernate.tool.hbm2ddl.SchemaExport execute
INFO: HHH000230: Schema export complete
Hibernate: insert into Customers (email, name) values (?, ?)
Hibernate: insert into Orders (cId, customers_cID, date) values (?, ?, ?)
Hibernate: insert into Orders (cId, customers_cID, date) values (?, ?, ?)
And this is the result tables:
Why the cID in Orders table (which is a foreign key references to customers) is 0?
It should be 1.
It think in your orders table customers_cId is the actual foreign key reference column to the customers table. As you haven't gave any column name explicitly, it internally took column name as customers_cId by joining the variables from both the entities. customers from the orders and cId from the customers entity.
Just to verify you can try giving some other name using #JoinColumn annotation.
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name="order_cId")
private Customers customers;
And cId in orders table is just one more independent column, as you have not set any value to it, its taking the default value as 0. Try setting some random value to it.
I am working on a project and using Hibernate for database interaction.
I have two tables, one is RESOURCE_PROFILE and second is PROJECT_MASTER. Below are the DDL statements.
CREATE TABLE USER_PROFILE (
FIRST_NAME VARCHAR(15) NOT NULL,
MIDDLE_NAME VARCHAR(15),
LAST_NAME VARCHAR(15) NOT NULL,
EMAIL_ID VARCHAR(40) NOT NULL,
USER_ID VARCHAR(40) NOT NULL,
PASSWORD VARCHAR(1000) NOT NULL,
ROLE VARCHAR(20),
SUPERVISOR_ID VARCHAR(20),
SUBMITTED_BY VARCHAR(20),
SUBMITTED_DATE DATE,
PRIMARY KEY (USER_ID)
);
CREATE TABLE PROJECT_MASTER (
PROJECT_ID INT NOT NULL AUTO_INCREMENT,
PROJECT_NAME VARCHAR(50) NOT NULL,
PROJECT_NUMBER VARCHAR(50) NOT NULL,
START_DATE DATE,
END_DATE DATE,
PROJECT_MANAGER_ID VARCHAR(40) NOT NULL,
PROJECT_SUPERVISOR_ID VARCHAR(40) NOT NULL,
SUBMITTED_BY VARCHAR(40),
SUBMITTED_DATE DATE,
UPDATED_BY VARCHAR(40),
PRIMARY KEY (PROJECT_ID),
FOREIGN KEY (PROJECT_MANAGER_ID) REFERENCES USER_PROFILE(USER_ID),
FOREIGN KEY (PROJECT_SUPERVISOR_ID) REFERENCES USER_PROFILE(USER_ID),
FOREIGN KEY (SUBMITTED_BY) REFERENCES USER_PROFILE(USER_ID),
FOREIGN KEY (UPDATED_BY) REFERENCES USER_PROFILE(USER_ID)
);
As you can see in the PROJECT_MASTER table I am using the USER_ID(RESOURCE_PROFILE) as a foreign key for multiple columns in PROJECT_MASTER table. Below is the entity class I created for these two tables. I am sure that I am doing something wrong in the mapping, can you please help me and point me to the right direction?
Since I have the same foreign key getting used for multiple columns, how can I achieve this mapping?
#Entity
#Table(name = "PROJECT_MASTER")
public class ProjectMasterBean {
#Id
#GeneratedValue
#Column(name="PROJECT_ID")
private int projectID;
#Column(name="PROJECT_NAME")
private String projectName;
#Column(name="PROJECT_NUMBER")
private String projectNumber;
#Column(name="START_DATE")
private Date startDate;
#Column(name="END_DATE")
private Date endDate;
#ManyToOne
#JoinColumn(name="USER_ID",insertable=false, updatable=false,
nullable=false)
private UserProfileBean projectManagerID;
#ManyToOne
#JoinColumn(name="USER_ID",insertable=false, updatable=false,
nullable=false)
private UserProfileBean projectSupervisorID;
#ManyToOne
#JoinColumn(name="USER_ID",insertable=false, updatable=false,
nullable=false)
private UserProfileBean submittedBy;
}
#Column(name="SUBMITTED_DATE")
private Date submittedDate;
#ManyToOne
#JoinColumn(name="USER_ID",insertable=false, updatable=false,
nullable=false)
private UserProfileBean updatedBy;
public class UserProfileBean {
#Id
#Column(name="USER_ID")
private String userID;
#Column(name="FIRST_NAME")
private String firstName;
#Column(name="MIDDLE_NAME")
private String middleName;
#Column(name="LAST_NAME")
private String lastName;
#Column(name="EMAIL_ID")
private String emailID;
#Column(name="PASSWORD")
private String password;
#Column(name="ROLE")
private String userRole;
#Column(name="SUPERVISOR_ID")
private String supervisorID;
#Column(name="SUBMITTED_BY")
private String submittedBy;
#Column(name="SUBMITTED_DATE")
private String submittedDate;
}
This is the exception I am getting:
Hibernate: insert into PROJECT_MASTER (PROJECT_NAME, PROJECT_NUMBER, START_DATE, END_DATE, SUBMITTED_BY, SUBMITTED_DATE, UPDATED_BY) values (?, ?, ?, ?, ?, ?, ?)
Sep 12, 2013 8:46:20 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet action threw exception
java.sql.SQLException: Field 'PROJECT_MANAGER_ID' doesn't have a default value
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3609)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3541)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2002)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2163)
Insert Query doesn't even have those two columns. This is how the query should be.
Hibernate: insert into PROJECT_MASTER (PROJECT_NAME, PROJECT_NUMBER, START_DATE, END_DATE, PROJECT_MANAGET_ID , PROJECT_SUPERVISOR_ID , SUBMITTED_BY, SUBMITTED_DATE, UPDATED_BY) values (?, ?, ?, ?, ?, ?, ?,?,?)
You've created your table with
CREATE TABLE PROJECT_MASTER ( PROJECT_ID INT NOT NULL AUTO_INCREMENT,
PROJECT_NAME VARCHAR(50) NOT NULL, PROJECT_NUMBER VARCHAR(50) NOT
NULL, START_DATE DATE, END_DATE DATE, PROJECT_MANAGER_ID VARCHAR(40)
NOT NULL, PROJECT_SUPERVISOR_ID VARCHAR(40) NOT NULL, SUBMITTED_BY
VARCHAR(40), SUBMITTED_DATE DATE, UPDATED_BY VARCHAR(40), PRIMARY KEY
(PROJECT_ID), FOREIGN KEY (PROJECT_MANAGER_ID) REFERENCES
USER_PROFILE(USER_ID), FOREIGN KEY (PROJECT_SUPERVISOR_ID) REFERENCES
USER_PROFILE(USER_ID), FOREIGN KEY (SUBMITTED_BY) REFERENCES
USER_PROFILE(USER_ID), FOREIGN KEY (UPDATED_BY) REFERENCES
USER_PROFILE(USER_ID) );
And you've made your class uses this Table. Because you don't have a default value for a NOT NULL field, Hibernate complains. Either delete that column from the table or add a relationship in your entity mapping.
Change to
#ManyToOne
#JoinColumn(name="PROJECT_MANAGER_ID ",insertable=false, updatable=false,
nullable=false)
private UserProfileBean projectManagerID;