my classes seem to be mapped correctly (if I try persist an object it creates the table in the DB (if it's missing)) and I can query succesfully, but I can't get a newly created instance to be persisted to the DB.
I have show SQL queries in console, and it's not generating the insert query, but it's trying to select(max) id afterwards
Could someone please help me figure out why?
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
User myUser = new User();
myUser.setUserId("Acccc");
myUser.setPassword("abc");
session.save(myUser);
and class:
#Entity
#Table(name = "users")
#SuppressWarnings("serial")
public class User implements Serializable
{
//Properties
#Id
#Column
private int id;
#Column
private String userId;
#Column
private String password;
//Getters
public int getId() { return id; }
public String getUserId() { return userId; }
public String getPassword() { return password; }
//Setters
public void setId(int id) { this.id = id; }
public void setUserId(String userId) { this.userId = userId; }
public void setPassword(String password) { this.password = password; }
}
and config:
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="nz.co.genesis.healthsafety.stripes.model.User" table="users">
<id name="id" type="int" column="id" >
</id>
<property name="userId" type="java.lang.String" column="userId" not-null="false" length="45" />
<property name="password" type="java.lang.String" column="password" not-null="false" length="45" />
</class>
</hibernate-mapping>
And DB:
id : PK NN AI
userId varchar45, default NULL
password varchar45, default: null
This is my code for test hibernate model
public static void main(String[] args) {
Properties props = new Properties();
props.setProperty("hibernate.dialect", "org.hibernate.dialect.SQLServerDialect");
props.setProperty("hibernate.connection.driver_class", "com.microsoft.jdbc.sqlserver.SQLServerDriver");
props.setProperty("hibernate.connection.url", "jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=databaseName");
props.setProperty("hibernate.connection.username", "username");
props.setProperty("hibernate.connection.password", "password");
props.setProperty("hibernate.show_sql", "true");
props.setProperty("hibernate.transaction.flush_before_completion", "true");
props.setProperty("hibernate.connection.release_mode", "auto");
props.setProperty("hibernate.transaction.auto_close_session", "true");
Configuration cfg = new Configuration();
cfg.setProperties(props);
// add dependency table class
cfg.addClass(ComputerModel.class);
cfg.addClass(CpuModel.class);
cfg.addClass(CdRomModel.class);
cfg.addClass(BrandModel.class);
SessionFactory sessions = cfg.buildSessionFactory();
Session ss = sessions.openSession();
List<ComputerModel> list = (ss.createQuery("from ComputerModel ")).list();
System.out.println("Found : " + list.size() + " items.");
System.out.println("======================================");
for (int i = 0; i < list.size(); i++) {
ComputerModel result = (ComputerModel) list.get(i);
System.out.println("computerSerialNo: " + result.getComputerSerialNo() +
", " + result.getCpuModel());
}
ss.close();
sessions.close();
}
I don't think you configuration of the Transaction Hibernate
Related
I have a program that works smoothly on MySQL database. Now for external requirements, I must switch to SQL Server. Thanks to Hibernate the switch was smooth, except for the error:
java.sql.SQLException: ResultSet may only be accessed in a forward direction.
I am getting this error when performing a custom pagination on the data that I get from the database. Below is a minimal example that tries to get and paginate the users stored in the database (the following example assumes that there are at least 3 rows in the table).
Custom pagination:
import org.hibernate.Query;
import org.hibernate.Session;
public class newMain1 {
public static void main(String[] args) {
getList(1, getSession());
getList(2, getSession());
}
private static void getList(int page, Session s) {
int rowsPerPage = 2;
String hql = "FROM User u ";
try {
Query query = s.createQuery(hql);
int start = (page - 1) * rowsPerPage;
query.setFirstResult(start);
query.setMaxResults(rowsPerPage);
//line that throws exception when int page is 2
query.list();
//line that throws exception when int page is 2
} finally {
if (s.isOpen()) {
s.close();
}
}
}
private Session getSession(){
//gets org.hibernate.Session
}
}
User Java POJO:
public class User {
private Long id;
private String username;
private String password;
private String email;
public User() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
User table for SQL Server:
CREATE TABLE [USER] (
ID bigint NOT NULL,
USERNAME varchar(150) NOT NULL UNIQUE,
PASSWORD varchar(150) NOT NULL,
EMAIL varchar(150) NOT NULL UNIQUE,
PRIMARY KEY (ID)
);
Hibernate mapping of User POJO:
<?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>
<class name="product.model.User" table="USER">
<id column="ID" name="id" type="long">
<generator class="increment"/>
</id>
<property column="EMAIL" name="email" type="string"/>
<property column="USERNAME" name="username" type="string"/>
<property column="PASSWORD" name="password" type="string"/>
</class>
</hibernate-mapping>
Hibernate cfg xml:
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>
<property name="hibernate.connection.driver_class">net.sourceforge.jtds.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:jtds:sqlserver://127.0.0.1:1433;DatabaseName=myDB;prepareSQL=3;sendStringParametersAsUnicode=false;</property>
<property name="hibernate.connection.username">sa</property>
<property name="hibernate.connection.password">myPassword</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.globally_quoted_identifiers">true</property>
<mapping resource="product_mapping/user.hbm.xml"/>
</session-factory>
I am using SQL Server 2012, JDK 1.8, Hibernate 4.0.1.Final, jtds driver 1.3.1
Please note that getList(1, getSession()) will not throw the exception, whereas getList(2, getSession()) will.
After hours of investigation i have find out that this problem was due to the hibernate dialect that i was using.
The correct dialect, considering the hibernate version i am required to use, is: org.hibernate.dialect.SQLServer2008Dialect
Source: https://forum.hibernate.org/viewtopic.php?p=2452163
I'm hoping you can help me solve this.
I'm trying to use hibernate 5.2 on my web java project. So far, I have managed to make the connection with the database using the hibernate.cfg.xml file, also I'm using hbm files like the one below to make the class mapping. I'm not using annotations on the models since I'm using hbm files. And now I'm trying to test everything by retrieving and object from the database using findById() method, but I'm getting the following error:
[ERROR ] SRVE0315E: Se ha producido una excepción: java.lang.Throwable: org.hibernate.UnknownEntityTypeException: Unable to locate persister: com.upy.model.Usuario
at com.ibm.ws.webcontainer.webapp.WebApp.handleRequest(WebApp.java:5000)
at [internal classes]
Caused by: org.hibernate.UnknownEntityTypeException: Unable to locate persister: com.upy.model.Usuario
at org.hibernate.metamodel.internal.MetamodelImpl.locateEntityPersister(MetamodelImpl.java:637)
at org.hibernate.internal.SessionImpl.locateEntityPersister(SessionImpl.java:2942)
at org.hibernate.internal.SessionImpl.access$1800(SessionImpl.java:203)
at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.<init>(SessionImpl.java:2693)
at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.<init>(SessionImpl.java:2679)
at org.hibernate.internal.SessionImpl.byId(SessionImpl.java:1200)
at org.hibernate.internal.SessionImpl.get(SessionImpl.java:1073)
at com.upy.dao.HibernateDAO.findById(HibernateDAO.java:45)
at com.upy.dao.UsuarioDAO.validarUsuario(UsuarioDAO.java:35)
at com.upy.servlets.LoginServlet.doGet(LoginServlet.java:116)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
... 1 more
I don't know why this is happening. This is my method for building the sessionFactory in a class called HibernateDAO:
public class HibernateDAO {
private static SessionFactory sessionFactory;
private static Session session;
protected void iniciarOperacion()
{
try
{
Configuration configuration = new Configuration().configure();
StandardServiceRegistryBuilder ssrb = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
sessionFactory = configuration.buildSessionFactory(ssrb.build());
session = sessionFactory.openSession();
}
catch (HibernateException he)
{
System.err.println("Error creating Session: " + he);
throw new ExceptionInInitializerError(he);
}
}
protected void cerrarOperacion(){
//getSessionFactory().close();
}
public static SessionFactory getSessionFactory()
{
return sessionFactory;
}
#SuppressWarnings("rawtypes")
public Object findById(Class clase, Serializable id){
try{
iniciarOperacion();
Object objeto = (Object) getSessionFactory().openSession().get(clase, id);
if(objeto!=null){
return objeto;
}else{
return null;
}
}catch(RuntimeException ex){
throw ex;
}finally{
getSessionFactory().close();
}
}
This is my Usuario.java and next the Usuario.hbm.xml:
package com.upy.model;
public class Usuario implements java.io.Serializable {
private Integer id;
private String username;
private String password;
private String email;
private Rol rol;
public Usuario() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Rol getRol() {
return rol;
}
public void setRol(Rol rol) {
this.rol = rol;
}
}
The Usuario.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD
3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- Generated 13-may-2017 19:29:28 by Hibernate Tools 4.0.0 -->
<hibernate-mapping>
<class name="com.upy.model.Usuario" table="usuario" schema="public">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="seqhilo">
<param name="sequence">public.rol_id_seq</param>
</generator>
</id>
<property name="username" type="string">
<column name="username" />
</property>
<property name="password" type="string">
<column name="password" />
</property>
<property name="email" type="string">
<column name="email" />
</property>
<many-to-one name="rol" class="com.upy.model.Rol" fetch="select"
lazy="false">
<column name="rol_id" not-null="true" />
</many-to-one>
</class>
</hibernate-mapping>
Finally, this is what I'm trying to execute in UsuarioDAO:
public boolean validarUsuario(String usuario, String password){
try{
//iniciarOperacion();
Usuario user = (Usuario) findById(Usuario.class, usuario);
if(user == null || !user.getPassword().equals(password)){
return false;
}else {
return true;
}
}catch(RuntimeException ex){
throw ex;
}finally{
cerrarOperacion();
}
}
The hbm file of Usuario is on resources folder inside src/main/resources and the model is on src/main/java/model
Thanks in advance for the help!
I solved the problem. It was such a silly mistake of mine. In the iniciarOperacion() method, im opening and closing the sessionFactory attribute, which should be inmutable. It should be only one sessionFactory per app and one should use session or getCurrentSession() method from there, since those are real connections to the database per request or use.
Thanks either way.
I'm trying to learn Hibernate using MySQL built-in database named world. It has three tables called city, country and countrylanguage. What I'm trying to do is execute SQL statement SELECT * FROM world.city;. When I run my project I'm getting error
org.hibernate.hql.internal.ast.QuerySyntaxException: City is not mapped [from City]
I'm using IntelliJ IDEA and Hibernate 5.2.8.
I created mapping xml file like this:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="pl.hibernatePackage">
<class name="City" table="city">
<id name="id" column="ID" type="int">
<generator class="native"/>
</id>
<property name="name" column="Name" type="string"/>
<property name="countryCode" column="CountryCode" type="string"/>
<property name="district" column="District" type="string"/>
<property name="population" column="Population" type="int"/>
</class>
</hibernate-mapping>
City.java is presented below:
public class City
{
private Integer id;
private String name;
private String countryCode;
private String district;
private Integer population;
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;
}
public String getCountryCode() {
return countryCode;
}
public void setCountryCode(String countryCode) {
this.countryCode = countryCode;
}
public String getDistrict() {
return district;
}
public void setDistrict(String district) {
this.district = district;
}
public Integer getPopulation() {
return population;
}
public void setPopulation(Integer population) {
this.population = population;
}
}
I'm creating session in HibernateUtil.java
public class HibernateUtil
{
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
Configuration configuration = new Configuration();
configuration.configure();
StandardServiceRegistryBuilder standardServiceRegistryBuilder = new StandardServiceRegistryBuilder();
standardServiceRegistryBuilder.applySettings(configuration.getProperties());
ServiceRegistry serviceRegistry = standardServiceRegistryBuilder.build();
return configuration.buildSessionFactory(serviceRegistry);
}
catch(Exception e) {
throw new ExceptionInInitializerError(e);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
Configuration file
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/world</property>
<property name="hibernate.connection.username">test</property>
<property name="hibernate.connection.password">1234</property>
<property name="connection.pool_size">1</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="current_session_context_class">thread</property>
<property name="show_sql">false</property>
<property name="hbm2ddl.auto">update</property>
<!-- List of XML mapping files -->
<mapping resource="pl/hibernatePackage/City.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Main
public class Main
{
public static void main(String[] args)
{
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
List<City> cities = session.createQuery("from City").list();
for(City c : cities) {
System.out.println(c.getId() + "\t" + c.getName() + "\t" + c.getCountryCode() + "\t" + c.getDistrict() +
"\t" + c.getPopulation());
}
session.getTransaction().commit();
HibernateUtil.getSessionFactory().close();
}
}
EDIT Full error list
EDIT 2
javac result
I have done some testing and i made it work by using the fully qualified class name:
session.createQuery("from pl.hibernatePackage.City")
Now this is only a workaround without touching your config..
After digging deeper i found out that since hibernate version 5.x, there is a different strategy for building the sessionFactory.
I made your example work by implementing sessionFactory as follows:
StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder()
.configure()
.build();
Metadata metadata = new MetadataSources( standardRegistry )
.getMetadataBuilder()
.build();
return configuration.buildSessionFactory(serviceRegistry);
This is explained with example here: jboss documentation (point 2.4)
Thanks to Maciej's answer and help of other guys I managed to get my example to work by modifying code and cleaning it up a little. I also found out that mapping DB with xml file is outdated so I modifiied properly CityEntity class. Final code:
Main.java
import org.hibernate.Session;
import java.util.List;
public class Main
{
public static void main(String[] args)
{
Session session = HibernateUtil.getSession();
session.beginTransaction();
List<CityEntity> cities = session.createQuery("from CityEntity").list();
for(CityEntity c : cities)
{
System.out.println(c.getId() + "\t" + c.getName() + "\t" + c.getCountryCode() + "\t" + c.getDistrict() +
"\t" + c.getPopulation());
}
session.getTransaction().commit();
HibernateUtil.close();
}
}
hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/world</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">1234</property>
<property name="connection.pool_size">1</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<!-- List of mapped classes -->
<mapping class="CityEntity"/>
</session-factory>
</hibernate-configuration>
HibernateUtil.java
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
public class HibernateUtil
{
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
Configuration configuration = new Configuration();
configuration.configure();
StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder()
.configure()
.build();
return configuration.buildSessionFactory(standardRegistry);
}
catch(Exception e) {
throw new ExceptionInInitializerError(e);
}
}
public static Session getSession()
{
return sessionFactory.openSession();
}
public static void close()
{
sessionFactory.close();
}
}
CityEntity.java
import javax.persistence.*;
#Entity
#Table(name = "city", schema = "world")
public class CityEntity
{
private int id;
private String name;
private String countryCode;
private String district;
private int population;
#Basic
#Column(name = "CountryCode")
public String getCountryCode() {
return countryCode;
}
public void setCountryCode(String countryCode) {
this.countryCode = countryCode;
}
#Id
#Column(name = "ID")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Basic
#Column(name = "Name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Basic
#Column(name = "District")
public String getDistrict() {
return district;
}
public void setDistrict(String district) {
this.district = district;
}
#Basic
#Column(name = "Population")
public int getPopulation() {
return population;
}
public void setPopulation(int population) {
this.population = population;
}
}
As per the document i read here it says :
Hibernate save method returns the generated id immediately, this is possible because primary object is saved as soon as save method is invoked.
But in my example below, i have fired the save method and then kept the thread on sleep for 1 minute.
Within this timespace when i check the database the person_o table doesnt show any data in it. why isnt it showing the age and name value in it immediately after save. though it appears after the commit is executed once sleep is over .
addperson.java:
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class addperson {
public static void main(String as[])
{
//Activate Hibernate Software
Configuration cfg=new Configuration();
//make hibernate software locating and reading cfg file
cfg=cfg.configure("/hibernate.cfg.xml");
//create SessionFactory obj
SessionFactory factory=cfg.buildSessionFactory();
//create HB session obj
Session session=factory.openSession();
Transaction tx = session.beginTransaction();
try {
// Create a person
person person = new person();
person.setName("Luna");
person.setAge(33);
Integer key = (Integer) session.save(person);
System.out.println("Primary Key : " + key);
person.setId(key);
System.out.println("---going for sleep---");
Thread.sleep(60000);
// Create the address for the person
personaddress address = new personaddress();
address.setAddressLine1("Lunaris");
address.setCity("Twinkle");
address.setState("MA");
address.setZipCode(10308);
address.setPerson(person);
person.setAddress(address);
key = (Integer) session.save(address);
System.out.println("Primary Key again : " + key);
tx.commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
} finally {
session.close();
}
}
}
person.java
import java.io.Serializable;
public class person implements Serializable {
private static final long serialVersionUID = -9127358545321739524L;
private int id;
private String name;
private int age;
private personaddress address;
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 int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public personaddress getAddress() {
return address;
}
public void setAddress(personaddress address) {
this.address = address;
}
}
personaddress.java
import java.io.Serializable;
public class personaddress implements Serializable {
private static final long serialVersionUID = -9127358545321739523L;
private int id;
private String addressLine1;
private String city;
private String state;
private int zipCode;
private person person;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAddressLine1() {
return addressLine1;
}
public void setAddressLine1(String addressLine1) {
this.addressLine1 = addressLine1;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public int getZipCode() {
return zipCode;
}
public void setZipCode(int zipCode) {
this.zipCode = zipCode;
}
public person getPerson() {
return person;
}
public void setPerson(person person) {
this.person = person;
}
}
hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="hibernate.connection.url">jdbc:oracle:thin:#localhost:1521:xe</property>
<property name="hibernate.connection.username">system</property>
<property name="hibernate.connection.password">oracle123</property>
<property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property>
<property name="hibernate.hbm2ddl.auto">create</property>
<property name="show_sql">true</property>
<mapping resource="person.hbm.xml"/> <mapping resource="personaddress.hbm.xml"/>
</session-factory>
</hibernate-configuration>
person.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">
<hibernate-mapping >
<class name="person" table="persons_o">
<id name="id" column="P_ID" type="integer">
<generator class="increment" />
</id>
<property name="name" column="NAME" update="false"
type="string" />
<property name="age" column="AGE" type="integer" />
<one-to-one name="address" cascade="all"></one-to-one>
</class>
</hibernate-mapping>
personaddress.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">
<hibernate-mapping>
<class name="personaddress" table="address_o"
dynamic-insert="true" dynamic-update="true"
select-before-update="false">
<id name="id" column="A_ID" type="integer">
<generator class="increment" />
</id>
<property name="addressLine1" column="ADDRESS_LINE_1"
type="string" />
<property name="city" column="CITY" type="string" />
<property name="state" column="STATE" type="string" />
<property name="zipCode" column="ZIPCODE" type="integer" />
<!-- In One-to-one we cannot specify the foreign key column
that has to be filled up
<one-to-one name="person" class="PersonOTO_B" cascade="all"
constrained="true"> </one-to-one>
-->
<many-to-one name="person" column="P_ID" unique="true"
not-null="true" lazy="false" />
</class>
</hibernate-mapping>
My output is :
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Hibernate: select max(P_ID) from persons_o
Primary Key : 1
---going for sleep--- (i am checking my db at this point but no data found )
Hibernate: select max(A_ID) from address_o
Primary Key again : 1
Hibernate: insert into persons_o (NAME, AGE, P_ID) values (?, ?, ?)
Hibernate: insert into address_o (ADDRESS_LINE_1, CITY, STATE, ZIPCODE, P_ID, A_ID) values (?, ?, ?, ?, ?, ?)
Please correct my knowledge.
Thanks
Jayendra Bhatt
session.save(Object), sesson.saveOrUpdate(Object) and etc. method only converts any transient object into persistence object,
means object associates with current hibernate session(actually object associates with session functional queues e.g. insertion queue,
updation queue and etc. according to corresponding operation) and gets hibernate generated(provided by generator class) id
if it's a new object. it never means that object will be immediately mapped on database.
When current hibernate session flushes or hibernate transaction commits then only actual query runs to map object data
into the database.
While trying to run the following program :
public class Runner {
public static void main(String args[]) {
Configuration config = new Configuration().configure();
SessionFactory sessFact = config.buildSessionFactory();
Session sess = sessFact.openSession();
Transaction trans = sess.beginTransaction();
Person p = new Person();
p.setPersonName("Suhail");
Set<String> set = new HashSet<String>();
set.add("Address-1");
set.add("Address-2");
set.add("Address-3");
p.setAddressSet(set);
sess.save(p);
trans.commit();
}
}
I am getting :
SEVERE: IllegalArgumentException in class: pojo.Address, getter method
of property: addressID
Exception in thread "main" org.hibernate.PropertyAccessException:
IllegalArgumentException occurred calling getter of pojo.Address.addressID
I don't know the reason for this. I am trying to make one to many association between Person and Address class.
mapping xml:
<hibernate-mapping>
<class name="pojo.Person" table="person">
<id name="personID" column="p_id">
<generator class="increment" />
</id>
<property name="personName" column="p_name" />
<set name="addressSet" table="address" cascade="all">
<key column="p_id" />
<one-to-many class="pojo.Address" />
</set>
</class>
<class name="pojo.Address" table="address">
<id name="addressID" column="a_id">
<generator class="increment" />
</id>
<property name="personAddress" column="p_address" />
</class>
</hibernate-mapping>
POJO:
Person
public class Person {
private int personID;
private String personName;
private Set addressSet;
public int getPersonID() {
return personID;
}
public void setPersonID(int personID) {
this.personID = personID;
}
public String getPersonName() {
return personName;
}
public void setPersonName(String personName) {
this.personName = personName;
}
public Set getAddressSet() {
return addressSet;
}
public void setAddressSet(Set addressSet) {
this.addressSet = addressSet;
}
}
Address
public class Address {
private int addressID;
private String personAddress;
public int getAddressID() {
return addressID;
}
public void setAddressID(int addressID) {
this.addressID = addressID;
}
public String getPersonAddress() {
return personAddress;
}
public void setPersonAddress(String personAddress) {
this.personAddress = personAddress;
}
}
SQL that created table
CREATE TABLE person(p_id INTEGER,p_name TEXT,PRIMARY KEY(p_id));
CREATE TABLE address(a_id INTEGER,p_address TEXT);
In your example you add to adress set Strings. But in your configuration you specify Address class.So I think your problem in this lines:
Set<String> set = new HashSet<String>();
set.add("Address-1");
set.add("Address-2");
set.add("Address-3");
You need to change set to Set<Address> and add Address objects in set:
Set<Address> set = new HashSet<>();
Address address = new Address();
address.setPersonAddress("Address-1");
set.add(address);
You can do couple of things without Mapping xml file. Place #Embeddable on ur Pojo of
#Embeddable
#Entity
public class Address {
#Id
private int addressID;
private String personAddress;
public int getAddressID() {
return addressID;
}
public void setAddressID(int addressID) {
this.addressID = addressID;
}
public String getPersonAddress() {
return personAddress;
}
public void setPersonAddress(String personAddress) {
this.personAddress = personAddress;
}
}
Then on
public class Runner {
public static void main(String args[]) {
Configuration config = new Configuration().configure();
SessionFactory sessFact = config.buildSessionFactory();
Session sess = sessFact.openSession();
Transaction trans = sess.beginTransaction();
Person p = new Person();
p.setPersonName("Suhail");
#ElementCollection//To inform hibernate to save this in a seperate table
Set<String> set = new HashSet<String>();
set.add("Address-1");
set.add("Address-2");
set.add("Address-3");
p.setAddressSet(set);
sess.save(p);
trans.commit();
}
}
Better to use Annotations so that we get rid of writing .hbm.xml mapping File