Hibernate + MySQL simple batch insert extremely slow - java

I'm inserting 2500 records from Hibernate into a totally empty MySQL table. The insert is taking 5 minutes!
I've googled for hours and tried a few things like an autogenerated primary key but nothing seems to improve the performance.
An earlier version of my program was doing inserts concurrently (1 per thread with ~100 threads) and that was taking ~2 minutes. I thought batching should improve performance by ~10x but it seems to have backfired.
I'm using Google Cloud's MySQL with a db-f1-micro instance
This is what my table looks like (only table in the DB!):
CREATE TABLE `categories` (
`browse_node` varchar(60) NOT NULL,
`name` varchar(60) DEFAULT NULL,
`path` varchar(400) DEFAULT NULL,
`url` varchar(200) NOT NULL,
`level` int(11) NOT NULL,
PRIMARY KEY (`browse_node`)
)
This is the POJO:
package example.com;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* Represents a category from the categories table
*/
#Entity
#Table(name = "categories")
public class Category {
#Id
#Column(name = "browse_node")
private String browseNode;
#Column(name = "name")
private String name;
#Column(name = "path")
private String path;
#Column(name = "url")
private String url;
#Column(name = "level")
private int level;
public Category() {
}
public Category(String browseNode, String name, String path, String url, int level) {
this.browseNode = browseNode;
this.name = name;
this.path = path;
this.url = url;
this.level = level;
}
// Omitting setters/getters
}
Here's the code doing the insertion:
private static void writeCategoriesToDb(Map<String, Category> categories) {
StatelessSession session = sessionFactory.openStatelessSession();
// Session session = sessionFactory.openSession();
session.beginTransaction();
int i = 0;
int batchSize = 50;
for (Category category : categories.values()) {
session.insert(category);
// if (i % batchSize == 0) {
// session.flush();
// session.clear();
// }
// i++;
}
session.getTransaction().commit();
session.close();
}
And here's the config file:
<?xml version='1.0' encoding='utf-8'?>
<!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>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://someIp/myDB</property>
<property name="connection.username">root</property>
<property name="connection.password">password</property>
<property name="connection.useSSL">false</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">20</property>
<property name="hibernate.jdbc.batch_size">3000</property>
<property name="hibernate.id.new_generator_mappings">false</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<mapping class="example.com.Category"/>
</session-factory>
</hibernate-configuration>

Found the answer here.
Adding rewriteBatchedStatements=true to my JDBC url fixed it!
It now takes ~2.2 seconds to insert all the records.
<property name="connection.url">jdbc:mysql://someIp/myDB?rewriteBatchedStatements=true</property>

Related

Hibernate 5 PropertyAccessException: Error accessing field by reflection for persistent property

I'm using hibernate to save an object to the db (mysql) but I keep getting an this error which doesn't really make sense to me since I have getters and setters from #Data (also tried with the vanilla way, the same error)
org.hibernate.property.access.spi.PropertyAccessException:
Error accessing field [private java.lang.String com.corona.models.User.email]
by reflection for persistent property [com.corona.models.User#email] :
User{id=0, email='asd#asd.asd', password='$2a$10$6lZ9wdyT.EyNXO5iIxfeeu9gX9hk8WAlwyykxQ9qIeZmyb3nKK4K6'}
at com.corona.dao.UserDao.saveEmployee(UserDao.java:18)
at com.corona.auth.AuthApplication.register(AuthApplication.java:28)
Caused by: java.lang.IllegalArgumentException: Can not set
java.lang.String field com.corona.models.User.email to com.corona.models.User
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
The model:
package com.corona.models;
import lombok.Data;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "USERS")
#Data
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY, generator = "identity")
#Column(name = "id")
private int id;
#Column(name = "password")
private String password;
#Column(name = "email")
private String email;
#Override
public String toString() {
return "User{" +
"id=" + id +
", email='" + email + '\'' +
", password='" + password + '\'' +
'}';
}
}
Config:
<!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>
<!-- JDBC Database connection settings -->
<property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/coronaTime?useSSL=false</property>
<property name="connection.username">root</property>
<property name="connection.password">*******</property>
<property name="connection.pool_size">1</property>
<property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>
<property name="show_sql">true</property>
<property name="current_session_context_class">thread</property>
<property name="hibernate.dbcp.initialSize">5</property>
<property name="hibernate.dbcp.maxTotal">20</property>
<property name="hibernate.dbcp.maxIdle">10</property>
<property name="hibernate.dbcp.minIdle">5</property>
<property name="hibernate.dbcp.maxWaitMillis">-1</property>
<mapping class="com.corona.models.User" />
</session-factory>
</hibernate-configuration>
Save method:
public class UserDao {
private HibernateTemplate template;
public void saveEmployee(User u){
Transaction tx = null;
try {
var session= HibernateUtil.getSessionFactory().openSession();
tx = session.beginTransaction();
session.save(u);
tx.commit();
} catch (Exception e) {
if( tx!=null) {
tx.rollback();
}
e.printStackTrace();
}
}
}
You need to have constructors for saving hibernate object.
Please add the following annotations:
#AllArgsConstructor(access = AccessLevel.PACKAGE)
#NoArgsConstructor(access = AccessLevel.PACKAGE)
(access as per your requirements)
Read this for explanation:
Why does Hibernate require no argument constructor?

Hibernate envers is not updating manually added columns in REVINFO with annotation

I am using plain java to hibernate standalone application with Hibernate Envers for getting updates of changes made in table's columns, I am using sql server as my Database, and I am new in envers.
Here is my "CustomRevisionEntity.java"
#Entity
#AuditTable("REVINFO")
#RevisionEntity(CustomRevisionListener.class)
public class CustomRevisionEntity {
#Column (name = "USERNAME", length = 50)
private String username;
#Id
#GeneratedValue
#RevisionNumber
#Column (name = "REV", unique = true, nullable = false)
private int id;
#Temporal(TemporalType.DATE)
#Column (name = "REVTSTMP", nullable = false, length = 15)
#RevisionTimestamp
private Date timestamp;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Date getTimestamp() {
return timestamp;
}
public void setTimestamp(Date timestamp) {
this.timestamp = timestamp;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
CustomRevisionListener.java
public class CustomRevisionListener implements RevisionListener {
public void newRevision(Object revisionEntity) {
CustomRevisionEntity revision = (CustomRevisionEntity) revisionEntity ;
String userName = Hibernate_Connection.getloggedUser();
revision.setUsername(userName);
}
}
Hibernate.cfg.xml
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
<property name="hibernate.connection.url">jdbc:sqlserver://localhost:1433;instance=SQLEXPRESS_2012;DatabaseName=ETS_V11_DEV;integratedSecurity=true</property> -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> -->
<property name="show_sql">true</property>
<property name="use_sql_comments">true</property>
<property name="hbm2ddl.auto">update</property>
<mapping class= "Domain_hibernate_SQLServer.Domain"/>
<mapping class= "Domain_hibernate_SQLServer.CustomRevisionEntity"/>
</session-factory>
</hibernate-configuration>
Problem: While using hbm.xml file then it is adding value on username column,
but while I am using Annotation for getting value that time is taking null value as it is not recognizing extra column property that I have added, but
While using annotation, its inserting null values in username columns
It is taking values like this with annotation while seeing sql code on console
/* insert org.hibernate.envers.DefaultRevisionEntity
*/ insert
into
REVINFO
(REVTSTMP)
values
(?)
Table has only 3 columns, 1 is REV, i.e, autoincrement, 2nd is REVTSTMP, nd 3rd is USERNAME, and Its not taking username,
What I am missing, If you need more information then please comment
I think the problem comes from your annotation config so can post your hbm.xml file and the class used for the anotation config?

Hibernate updating from different sessions

I am porting a java fat client from JDBC SQLite to Hibernate H2.
Until now I tried to separate all my database code in separate classes, like
TableTeam or TableMember, which have methods like .getAllTeams() or .updateTeam(Team t). These methods acted as a wrapper around their sql queries they executed.
Now with hibernate I tried to leave the interface as good as possible and just change the SQL queries to hibernate functions, which mostly works.
With one exception: updating elements.
team = new Team(-1, "Team Name", Collections.<Member>emptySet());
#Test
public void testUpdateTeam() throws Exception {
table.addTeam(team);
team.setName("New Name");
table.updateTeam(team);
Team f = table.getAllTeams().get(0);
Assert.assertEquals(team, f);
}
results in the following exception:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: ch.tiim.sco.database.model.Team.members, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:576)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:215)
at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:156)
at org.hibernate.collection.internal.PersistentSet.size(PersistentSet.java:160)
at java.util.AbstractSet.equals(AbstractSet.java:92)
at org.hibernate.collection.internal.PersistentSet.equals(PersistentSet.java:441)
at ch.tiim.sco.database.model.Team.equals(Team.java:81)
at org.junit.Assert.isEquals(Assert.java:131)
at org.junit.Assert.equalsRegardingNull(Assert.java:127)
at org.junit.Assert.assertEquals(Assert.java:111)
at org.junit.Assert.assertEquals(Assert.java:144)
at ch.tiim.sco.database.TableMemberTest.testEditTeam(TableMemberTest.java:45)
The code for .updateTeam(Team t) is the following:
public void updateTeam(Team t) {
Session s = sessionFactory.getCurrentSession();
s.beginTransaction();
s.update(t);
s.getTransaction().commit();
}
And the same for .addTeam(Team t) but s.save(t) instead of s.update(t)
And Team looks like this:
#Entity
#Table(name = "team")
public class Team implements Model {
#Id
#GeneratedValue
#Column(name = "team_id")
private int id;
#Column(name = "name")
private String name;
#ManyToOne
#JoinColumn(name = "club_id")
private Club club;
#ManyToMany
#JoinTable(name = "team_members",
joinColumns = {#JoinColumn(name = "team_id")},
inverseJoinColumns = {#JoinColumn(name = "member_id")}
)
private java.util.Set<Member> members;
//I stripped the constructor and the setters/getters
}
Now how do I get rid of this error, without guaranteeing that every call to hibernate is from the same thread?
Edit Here is the hibernate configuration
<?xml version='1.0' encoding='utf-8'?>
<!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>
<!-- Database connection settings -->
<property name="connection.driver_class">org.h2.Driver</property>
<!--property name="connection.url">jdbc:h2:./test</property-->
<property name="connection.username">user</property>
<property name="connection.password">pass</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.H2Dialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<!--property name="show_sql">true</property-->
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create</property>
</session-factory>
</hibernate-configuration>
For Junit testcases you need to bind an opened Session to the current Thread.
SessionFactory sf = null;
Session s = null;
SessionHolder holder = null;
#Override
protected void onSetUp() throws Exception {
System.out.println("On SetUP----");
sf = (SessionFactory) beanFactory.getBean("sessionFactory");
s = sf.openSession();
TransactionSynchronizationManager.bindResource(sf, new SessionHolder(s));
}
#Override
protected void onTearDown() throws Exception {
System.out.println("On onTearDown----");
// unbind and close the session.
holder = (SessionHolder)TransactionSynchronizationManager.getResource(sf);
s = holder.getSession();
s.flush();
TransactionSynchronizationManager.unbindResource(sf);
SessionFactoryUtils.releaseSession(s, sf);
// teardown code here
}
If you want to no more care about LazyInitialisationException read this, its well explain what happens, and how to resolve the problem definitely
Can you post your hibernate.cfg? I suspect? you don't have a configured session context:
E.g
thread

Hibernate Table doesn't exist error

I really need your help.
I'm new t hibernate. Trying to save an object but all the time i'm getting error:
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'hibernate.person' doesn't exist
Here is domain object:
#Table(name = "Person")
#Entity
public class Person {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private String id;
#Column(name = "Person_age")
private int age;
#Column(name = "Person_name")
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Here is my hibernate config file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/hibernate</property>
<property name="connection.username">root</property>
<property name="connection.password">******</property>
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Show all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create</property>
<!-- Mapping files -->
<mapping class="ua.macko.domain.Person" />
</session-factory>
</hibernate-configuration>
The error i am getting is: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'hibernate.person' doesn't exist.
I was trying to set hbm2ddl.auto parameter to create and to update but that gave me no result.
Please tell me what am i doing wrong?
Thnx in advance
After adding javassist library the issue has been solved. Thanks to all for help!
<property name="hbm2ddl.auto">create</property>
Is wrong for hibernate.cfg.xml, use
<property name="hibernate.hbm2ddl.auto">create</property>
instead.

How to connect postgresql in hibernate.cfg.xml

I am trying to insert some data into postgresql through hibernate. However, there are not much tutorial about configurate hibernate with postgresql (I know, it should be similar to mysql =))
src/main/resources/hibernate.cfg.xml
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">org.postgresql.Driver</property>
<property name="connection.url">jdbc:postgresql://127.0.0.1:5432/myDatabase</property>
<property name="connection.username">myUser</property>
<property name="connection.password">myPassword</property>
<!-- JDBC connection pool (use the build-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
<property name="cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
<property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
<!-- thread is the short name for org.hibernate.context.ThreadLocalSessionContext -->
<property name="current_session_context_class">thread</property>
<!-- Set "true" to show SQL statements -->
<property name="hibernate.show_sql">true</property>
<!-- mapping class using annotation -->
<mapping class="com.hib.entities.Student"></mapping>
</session-factory>
</hibernate-configuration>
src/main/java/
package com.hib.init;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
public class Hibernateutil {
private static final SessionFactory sessionF;
private static final ServiceRegistry serviceR;
static {
Configuration conf = new Configuration();
conf.configure();
System.out.println("Begin");
serviceR = new ServiceRegistryBuilder().applySettings(conf.getProperties()).buildServiceRegistry();
System.out.println("Ready???");
try {
sessionF = conf.buildSessionFactory(serviceR);
System.out.println("Success??");
}catch(Exception e) {
throw new ExceptionInInitializerError(e);
}
}
public static SessionFactory getSeeionFactory() {
return sessionF;
}
}
src/main/java
package com.hib.entities;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table
public class Student {
#Id
#GeneratedValue
private Integer id;
private String firstName;
private Integer age;
public Student() {}
public Student(Integer id, String firstName, Integer age) {
super();
this.id = id;
this.firstName = firstName;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
src/main/java
package com.hib.demo;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import com.hib.entities.Student;
import com.hib.init.Hibernateutil;
public class DemoFirst {
public static void main(String[] args) {
SessionFactory sessionFactory = Hibernateutil.getSeeionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
Student student = new Student();
student.setFirstName("Bob");
student.setAge(26);
session.save(student);
session.getTransaction().commit();
session.close();
}
}
And this is the error I got :
Success??
Hibernate: select nextval ('hibernate_sequence')
Aug 12, 2014 11:01:10 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 0, SQLState: 42P01
Aug 12, 2014 11:01:10 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: ERROR: relation "hibernate_sequence" does not exist
Position: 17
Exception in thread "main" org.hibernate.exception.SQLGrammarException: ERROR: relation "hibernate_sequence" does not exist
Position: 17
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:122)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:129)
at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
at com.sun.proxy.$Proxy9.executeQuery(Unknown Source)
at org.hibernate.id.SequenceGenerator.generateHolder(SequenceGenerator.java:123)
at org.hibernate.id.SequenceGenerator.generate(SequenceGenerator.java:116)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:120)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:204)
at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:55)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:189)
at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:49)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:642)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:635)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:631)
at com.hib.demo.DemoFirst.main(DemoFirst.java:20)
Caused by: org.postgresql.util.PSQLException: ERROR: relation "hibernate_sequence" does not exist
Position: 17
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2062)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1795)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:479)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:367)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:271)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122)
... 14 more
pom.xml
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>8.4-701.jdbc4</version>
</dependency>
According to this thread you must set your Id annotation as follows:
#GeneratedValue(strategy = GenerationType.IDENTITY)
You forgot to add the DDL auto generation property. You can use any of the following settings:
<property name="hibernate.hbm2ddl.auto" value="update">
<property name="hibernate.hbm2ddl.auto" value="create">
<property name="hibernate.hbm2ddl.auto" value="create-drop">
update is going to create and then simply update the DDL schema
create is going to create the schema if it doesn't exist
create-drop will create the schema when the SessionFactory is initialized and destroy it when the SessionFactory is destroyed. This is useful during integration testing.
You should make mapping beetwen table-entity class, column- field. For example (table and columns should exist) :
#Entity
#Table(name = "student")
public class Student {
#Id
#GeneratedValue
#Column(name = "id")
private Integer id;
#Column(name = "first_name")
private String firstName;
#Column(name = "age")
private Integer age;
Because you are using #GeneratedValue()
It will look for how the database that you are using generates ids. For MySql or HSQSL, there are increment fields that automatically increment. In Postgres or Oracle, they use sequence tables. Since you didn't specify a sequence table name, it will look for a sequence table named hibernate_sequence and use it for default. So you probably don't have such a sequence table in your database and now you get that error.
Either add a hibernate_sequence
like
#GeneratedValue(strategy=SEQUENCE)
or
your own sequence table and use the annotations to name your sequence table that you have like
#GeneratedValue(strategy=SEQUENCE, generator="student_id_seq")
Hope that helps
Connect to Postgresql by Hibernate -> configuration in hibernate.cfg.xml would be :
<session-factory>
<!-- SQL dialect -->
<!-- <property name="dialect">org.hibernate.dialect.H2Dialect</property> -->
<!-- Database connection settings -->
<property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
<property name="connection.url">jdbc:postgresql://localhost:5432/db_name</property>
<property name="connection.username">username</property>
<property name="connection.password">db_assword</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<!-- <property name="hbm2ddl.auto">validate</property> -->
<!-- The mapping information of entities -->
<!-- <mapping class="hibernate_example.envers.Book" /> -->
<!-- <mapping class="hibernate_example.envers.Student" /> -->
<!-- <mapping class="hibernate_example.envers.AuditEntity" /> -->
</session-factory>
Your id should look like:
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "my_id_gen")
#SequenceGenerator(name = "my_id_gen", sequenceName = "my_id_seq")
private Long id;
The sequenceName property should refer to the proper sequence in your database. If you created the column as sequence type, then it should be tableName_columnName_seq.

Categories

Resources