Why does hibernate drops foreing key constraint before creating tables? - java

Here is my simple hibernate.cfg.xml 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://localhost/UserDB</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQL5Dialect</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>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create-drop</property>
<!-- Mapping files -->
<mapping class="com.stackoverflow.model.Person" />
<mapping class="com.stackoverflow.model.Phone" />
</session-factory>
Here is simple Person entity:
#Entity(name = "Person")
public class Person {
#Id
#GeneratedValue
private Long id;
public Person() {
}
}
Here is simple Phone entity:
#Entity(name = "Phone")
public class Phone {
#Id
#GeneratedValue
private Long id;
#Column(name = "`number`")
private String number;
#ManyToOne(cascade=CascadeType.ALL,optional=false)
#JoinColumn(name = "person_id",
foreignKey = #ForeignKey(name = "PERSON_ID_FK")
)
private Person person;
public Phone() {
}
public Phone(String number) {
this.number = number;
}
public Long getId() {
return id;
}
public String getNumber() {
return number;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}
Here is junit test class that tries to save this relationship into database:
public class TestManyToOne {
private static SessionFactory sessionFactory;
private Session session;
#BeforeClass
public static void setUp() throws Exception {
// A SessionFactory is set up once for an application!
final StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure("hibernate.cfg.xml")
.build();
try {
sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
} catch (Exception e) {
// The registry would be destroyed by the SessionFactory, but we had
// trouble building the SessionFactory
// so destroy it manually.
StandardServiceRegistryBuilder.destroy(registry);
System.out.println("Exception\n" + e);
}
assertNotNull(sessionFactory);
}
#AfterClass
public static void tearDown() throws Exception {
sessionFactory.close();
}
#Before
public void beforeEach() {
session = sessionFactory.getCurrentSession();
session.beginTransaction();
}
#After
public void afterEach() {
session.getTransaction().commit();
session.close();
}
#Test
public void testSave() {
Person person = new Person();
Phone phone1 = new Phone("93283287832");
Phone phone2 = new Phone("0987654321");
phone1.setPerson(person);
phone2.setPerson(person);
session.save(phone1);
session.save(phone2);
}
}
It has only one #Test method called testSave. When I run it on just created database I get error :
Hibernate:
alter table Phone
drop
foreign key PERSON_ID_FK
апр 11, 2017 5:50:54 PM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess#6f2cfcc2] 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.
апр 11, 2017 5:50:54 PM org.hibernate.tool.schema.internal.ExceptionHandlerLoggedImpl handleException
WARN: GenerationTarget encountered exception accepting command : Error executing DDL via JDBC Statement
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL via JDBC Statement
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:62)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.applySqlString(SchemaDropperImpl.java:374)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.applySqlStrings(SchemaDropperImpl.java:359)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.applyConstraintDropping(SchemaDropperImpl.java:331)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.dropFromMetadata(SchemaDropperImpl.java:230)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.performDrop(SchemaDropperImpl.java:154)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.doDrop(SchemaDropperImpl.java:126)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.doDrop(SchemaDropperImpl.java:112)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:137)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:65)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:307)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:490)
at org.hibernate.boot.internal.MetadataImpl.buildSessionFactory(MetadataImpl.java:170)
at com.stackoverflow.dao.TestDao.setUp(TestDao.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:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:283)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:173)
Hibernate:
drop table if exists hibernate_sequence
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:128)
at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'userdb.phone' doesn't exist
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
at com.mysql.jdbc.Util.getInstance(Util.java:381)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1030)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3491)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3423)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1936)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2060)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2536)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2465)
at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:734)
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:49)
... 30 more
In error this line is important:
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'userdb.phone' doesn't exist
How to tell hibernate do not drop foreign key constraint before creating tables?
Thank you.

I didn't believe it but the problem was that connection pool size was set to 1. After I set it to ten
<property name="connection.pool_size">10</property>
junit test runs succesfully but the error didn't disappear. It is ignored by eclipse.

Related

How to connect to SQL Server 2017 using Hibernate and Windows Authentication?

Full MCVE is at the bottom of this post.
I am trying to run a very basic Hibernate example as I work through a tutorial. However, I am receiving the following error: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]:
Exception in thread "main" java.lang.ExceptionInInitializerError
at hibernateTutorial.util.HibernateUtil.buildSessionFactory(HibernateUtil.java:50)
at hibernateTutorial.util.HibernateUtil.getSessionFactory(HibernateUtil.java:30)
at hibernateTutorial.main.HibernateMain.main(HibernateMain.java:21)
Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:275)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:152)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:286)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:243)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:176)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:127)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:86)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:479)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:85)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:709)
at hibernateTutorial.util.HibernateUtil.buildSessionFactory(HibernateUtil.java:47)
... 2 more
Caused by: org.vibur.dbcp.ViburDBCPException: java.lang.NullPointerException
at org.vibur.dbcp.ViburDBCPDataSource.start(ViburDBCPDataSource.java:233)
at org.hibernate.vibur.internal.ViburDBCPConnectionProvider.configure(ViburDBCPConnectionProvider.java:57)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:107)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:246)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.buildJdbcConnectionAccess(JdbcEnvironmentInitiator.java:145)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:66)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
... 15 more
Caused by: java.lang.NullPointerException
at java.util.Hashtable.put(Hashtable.java:460)
at java.util.Properties.setProperty(Properties.java:166)
at org.vibur.dbcp.pool.Connector$Builder$Driver.<init>(Connector.java:66)
at org.vibur.dbcp.pool.Connector$Builder$Driver.<init>(Connector.java:56)
at org.vibur.dbcp.pool.Connector$Builder.buildConnector(Connector.java:48)
at org.vibur.dbcp.ViburDBCPDataSource.doStart(ViburDBCPDataSource.java:248)
at org.vibur.dbcp.ViburDBCPDataSource.start(ViburDBCPDataSource.java:226)
... 24 more
My database is on a Microsoft SQL Server 2017 instance that uses Windows Authentication. I have added both the MSSQL JDBC (v6.4.0) updated IntelliJ with the -Djava.library.path VM option so that sqljdbc_auth.dll (required for Windows Authentication) is accessible.
From what I can tell in my research into this ambiguous error message, it could have many different causes, but ultimately boils down to just not being able to connect to the database somehow. Most of the other Q&A I've found seems to be specific to other databases or SQL Server that doesn't use Windows Authentication.
I have copied the JDBC URL directly from my datasource config in IntelliJ so I know that it is correct and works properly in the IDE.
What else is required to properly configure Hibernate to connect to SQL Server?
HibernateMain.java:
package hibernateTutorial.main;
import hibernateTutorial.model.Employee;
import hibernateTutorial.util.HibernateUtil;
import org.hibernate.Session;
import java.time.LocalDateTime;
public class HibernateMain {
public static void main(String[] args) {
Employee emp = new Employee();
emp.setName("Nathan");
emp.setRole("CEO");
emp.setInsertTime(LocalDateTime.now());
// **********************************************************************************************
// Get Session
// **********************************************************************************************
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
// **********************************************************************************************
// Start transaction
// **********************************************************************************************
session.beginTransaction();
// **********************************************************************************************
// Save the model object
// **********************************************************************************************
session.save(emp);
// **********************************************************************************************
// Commit the transaction
// **********************************************************************************************
session.getTransaction().commit();
System.out.println("Employee ID: " + emp.getId());
// **********************************************************************************************
// Terminate the session factory or the program won't end
// **********************************************************************************************
HibernateUtil.getSessionFactory().close();
}
}
HibernateUtil.java:
package hibernateTutorial.util;
import hibernateTutorial.model.Employee1;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import java.util.Properties;
public class HibernateUtil {
// **********************************************************************************************
// XML-based configuration
// **********************************************************************************************
private static SessionFactory sessionFactory;
// **********************************************************************************************
// Annotation-based configuration
// **********************************************************************************************
private static SessionFactory sessionAnnotationFactory;
// **********************************************************************************************
// Property-based configuration
// **********************************************************************************************
private static SessionFactory sessionJavaConfigFactory;
public static SessionFactory getSessionFactory() {
if (sessionFactory == null) sessionFactory = buildSessionFactory();
return sessionFactory;
}
private static SessionFactory buildSessionFactory() {
try {
// **********************************************************************************************
// Create the SessionFactory from hibernate.cfg.xml
// **********************************************************************************************
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
System.out.println("Hibernate configuration loaded");
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
System.out.println("Hibernate serviceRegistry created");
return configuration.buildSessionFactory(serviceRegistry);
} catch (Throwable e) {
System.err.println("Initial SessionFactory creation failed. " + e);
throw new ExceptionInInitializerError(e);
}
}
public static SessionFactory getSessionAnnotationFactory() {
if (sessionAnnotationFactory == null) sessionAnnotationFactory = buildSessionAnnotationFactory();
return sessionAnnotationFactory;
}
private static SessionFactory buildSessionAnnotationFactory() {
try {
// **********************************************************************************************
// Create the SessionFactory from hibernate-annotation.cfg.xml
// **********************************************************************************************
Configuration configuration = new Configuration();
configuration.configure("hibernate-annotation.cfg.xml");
System.out.println("Hibernate Annotation configuration loaded");
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
System.out.println("Hibernate Annotation serviceRegistry created");
return configuration.buildSessionFactory(serviceRegistry);
} catch (Throwable e) {
System.err.println("Initial SessionFactory creationg failed." + e);
throw new ExceptionInInitializerError(e);
}
}
public static SessionFactory getSessionJavaConfigFactory() {
if (sessionJavaConfigFactory == null) sessionJavaConfigFactory = buildSessionJavaConfigFactory();
return sessionJavaConfigFactory;
}
private static SessionFactory buildSessionJavaConfigFactory() {
try {
Configuration configuration = new Configuration();
//Create Properties, can be read from property files too
Properties props = new Properties();
props.put("hibernate.connection.driver_class", "com.microsoft.sqlserver.jdbc.SQLServerDriver");
props.put("hibernate.connection.url", "jdbc:sqlserver://FADBOKT2493V\\KRAFTLAKEODB:51678;database=Dev_RepAssistDB;integratedSecurity=true");
props.put("hibernate.current_session_context_class", "thread");
configuration.setProperties(props);
//we can set mapping file or class with annotation
//addClass(Employee1.class) will look for resource
// com/journaldev/hibernate/model/Employee1.hbm.xml (not good)
configuration.addAnnotatedClass(Employee1.class);
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
System.out.println("Hibernate Java Config serviceRegistry created");
return configuration.buildSessionFactory(serviceRegistry);
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
}
Employee.java:
package hibernateTutorial.model;
import java.time.LocalDateTime;
public class Employee {
private int id;
private String name;
private String role;
private LocalDateTime insertTime;
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 String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public LocalDateTime getInsertTime() {
return insertTime;
}
public void setInsertTime(LocalDateTime insertTime) {
this.insertTime = insertTime;
}
}
Employee1.java:
package hibernateTutorial.model;
import javax.persistence.*;
import java.time.LocalDateTime;
#Entity
#Table(name = "tmp_employees",
uniqueConstraints =
{#UniqueConstraint(columnNames = {"id"})})
public class Employee1 {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = false, unique = true, length = 11)
private int id;
#Column(name = "name", length = 20, nullable = true)
private String name;
#Column(name = "role", length = 20, nullable = true)
private String role;
#Column(name = "insert_time", nullable = true)
private LocalDateTime insertTime;
}
employee.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"https://hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="hibernateTutorial.model.Employee" table="tmp_employees">
<id name="id" type="int">
<column name="id"/>
<generator class="increment"/>
</id>
<property name="name" type="java.lang.String">
<column name="name"/>
</property>
<property name="role" type="java.lang.String">
<column name="role"/>
</property>
<property name="insertTime" type="java.time.LocalDateTime">
<column name="insert_time"/>
</property>
</class>
</hibernate-mapping>
hibernate.cfg.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"https://hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection properties - Driver, URL, user, password -->
<property name="hibernate.connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
<property name="hibernate.connection.url">jdbc:sqlserver://servername:port;
database=test_db;integratedSecurity=true
</property>
<!-- Connection Pool Size -->
<property name="hibernate.connection.pool_size">5</property>
<!-- org.hibernate.HibernateException: No CurrentSessionContext configured! -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- Outputs the SQL queries, should be disabled in Production -->
<property name="hibernate.show_sql">true</property>
<!-- Dialect is required to let Hibernate know the Database Type, MySQL, Oracle etc
Hibernate 4 automatically figure out Dialect from Database Connection Metadata -->
<property name="hibernate.dialect">org.hibernate.dialect.SQLServer2012Dialect</property>
<!-- mapping file, we can use Bean annotations too -->
<mapping resource="hibernateTutorial/employee.hbm.xml"/>
</session-factory>
</hibernate-configuration>
hibernate-annotation.cfg.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"https://hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection properties - Driver, URL, user, password -->
<property name="hibernate.connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
<property name="hibernate.connection.url">jdbc:sqlserver:servername:port;database=test_db;integratedSecurity=true</property>
<!-- Connection Pool Size -->
<property name="hibernate.connection.pool_size">5</property>
<!-- org.hibernate.HibernateException: No CurrentSessionContext configured! -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- Outputs the SQL queries, should be disabled in Production -->
<property name="hibernate.show_sql">true</property>
<!-- Dialect is required to let Hibernate know the Database Type, MySQL, Oracle etc
Hibernate 4 automatically figure out Dialect from Database Connection Metadata -->
<property name="hibernate.dialect">org.hibernate.dialect.SQLServer2012Dialect</property>
<!-- mapping with model class containing annotations -->
<mapping class="hibernateTutorial.model.Employee1"/>
</session-factory>
</hibernate-configuration>

hibernate xml configuration seems not to work

I am learning hibernate, and trying to make xml configuration which seems not to work.
hibernate.cfg.xml
<?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>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">87654321</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/protein_tracker</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.default_schema">protein_tracker</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.hbm2ddl.auto">create</property>
<mapping resource="com/andrei/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
The <property name="hibernate.hbm2ddl.auto">create</property> does not work. I get exception: no available table in the database.
User.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="com.andrei.User" table="Users">
<id name="id" type="int">
<column name="ID" />
<generator class="identity" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
<property name="total" type="int">
<column name="TOTAL" />
</property>
<property name="goal" type="int">
<column name="GOAL" />
</property>
</class>
</hibernate-mapping>
In the user.hbm.xml I specify that the table is users, but the app looks for table user, which is exactly the name name of my entity.
User.class:
#Entity
//#Table(name="users")
public class User {
#Id
private int id;
private String name;
private int total;
private int goal;
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 getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public int getGoal() {
return goal;
}
public void setGoal(int goal) {
this.goal = goal;
}
}
If I uncomment the #Table annotation from the user class, the app looks for the correct (users) table. Why the xml configuration is not working?
Bellow you can see the hibernate helper class, and my main()
HibernateUtilities.java
public class HibernateUtilities {
private static SessionFactory sessionFactory;
private static ServiceRegistry serviceRegistry;
static {
try {
Configuration conf = new Configuration().configure();
conf.addAnnotatedClass(com.andrei.User.class);
conf.configure();
serviceRegistry = new StandardServiceRegistryBuilder().applySettings(conf.getProperties()).build();
sessionFactory = conf.buildSessionFactory(serviceRegistry);
} catch (HibernateException e) {
System.out.println("problem creating session factory: " + e);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
Main.java
public static void main(String[] args) {
Session session = HibernateUtilities.getSessionFactory().openSession();
session.beginTransaction();
User user = new User();
user.setName("first name");
user.setGoal(250);
session.save(user);
session.getTransaction().commit();
session.close();
HibernateUtilities.getSessionFactory().close();
}
Here are my questions
Why the xml configuration does not work? The table name specified in user.hbm.xml is users, but the app looks for table user.
Why <property name="hibernate.hbm2ddl.auto">create</property> does not work?
Here are my logs:
Hibernate: drop table if exists users Dec 26, 2017 4:55:42 PM
org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl
getIsolatedConnection INFO: HHH10001501: Connection obtained from
JdbcConnectionAccess
[org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess#4612b856]
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 users (id
integer not null, goal integer not null, name varchar(255), total
integer not null, primary key (id)) type=MyISAM Dec 26, 2017 4:55:42
PM
org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl
getIsolatedConnection INFO: HHH10001501: Connection obtained from
JdbcConnectionAccess
[org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess#74eb909f]
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. Dec 26, 2017 4:55:42 PM
org.hibernate.tool.schema.internal.ExceptionHandlerLoggedImpl
handleException WARN: GenerationTarget encountered exception accepting
command : Error executing DDL via JDBC Statement
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error
executing DDL via JDBC Statement at
org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:67)
at
org.hibernate.tool.schema.internal.SchemaCreatorImpl.applySqlString(SchemaCreatorImpl.java:440)
at
org.hibernate.tool.schema.internal.SchemaCreatorImpl.applySqlStrings(SchemaCreatorImpl.java:424)
at
org.hibernate.tool.schema.internal.SchemaCreatorImpl.createFromMetadata(SchemaCreatorImpl.java:315)
at
org.hibernate.tool.schema.internal.SchemaCreatorImpl.performCreation(SchemaCreatorImpl.java:166)
at
org.hibernate.tool.schema.internal.SchemaCreatorImpl.doCreation(SchemaCreatorImpl.java:135)
at
org.hibernate.tool.schema.internal.SchemaCreatorImpl.doCreation(SchemaCreatorImpl.java:121)
at
org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:155)
at
org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:72)
at
org.hibernate.internal.SessionFactoryImpl.(SessionFactoryImpl.java:313)
at
org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:452)
at
org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:710)
at com.andrei.HibernateUtilities.(HibernateUtilities.java:21)
at com.andrei.Program.main(Program.java:8) Caused by:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an
error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near 'type=MyISAM' at
line 1 at
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:425) at
com.mysql.jdbc.Util.getInstance(Util.java:408) at
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:944) at
com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3973) at
com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3909) at
com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2527) at
com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2680) at
com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2480) at
com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2438) at
com.mysql.jdbc.StatementImpl.executeInternal(StatementImpl.java:845)
at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:745) at
org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:54)
... 13 more
Dec 26, 2017 4:55:42 PM
org.hibernate.tool.schema.internal.SchemaCreatorImpl
applyImportSources INFO: HHH000476: Executing import script
'org.hibernate.tool.schema.internal.exec.ScriptSourceInputNonExistentImpl#2826f61'
Hibernate: insert into users (goal, name, total, id) values (?, ?, ?,
?) Dec 26, 2017 4:55:42 PM
org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions WARN:
SQL Error: 1146, SQLState: 42S02 Dec 26, 2017 4:55:42 PM
org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions ERROR:
Table 'protein_tracker.users' doesn't exist Dec 26, 2017 4:55:42 PM
org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl release
INFO: HHH000010: On release of batch it still contained JDBC
statements Dec 26, 2017 4:55:42 PM
org.hibernate.internal.ExceptionMapperStandardImpl
mapManagedFlushFailure ERROR: HHH000346: Error during managed flush
[org.hibernate.exception.SQLGrammarException: could not execute
statement] Exception in thread "main"
javax.persistence.PersistenceException:
org.hibernate.exception.SQLGrammarException: could not execute
statement at
org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:149)
at
org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:157)
at
org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:164)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1443)
at
org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:493)
at
org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3207)
at
org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2413)
at
org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:473)
at
org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:156)
at
org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38)
at
org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:231)
at
org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:68)
at com.andrei.Program.main(Program.java:17) Caused by:
org.hibernate.exception.SQLGrammarException: could not execute
statement at
org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:63)
at
org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
at
org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111)
at
org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:97)
at
org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:178)
at
org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:45)
at
org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3013)
at
org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3513)
at
org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:89)
at
org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:589)
at
org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:463)
at
org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337)
at
org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1437)
... 9 more Caused by:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table
'protein_tracker.users' doesn't exist at
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:425) at
com.mysql.jdbc.Util.getInstance(Util.java:408) at
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:944) at
com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3973) at
com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3909) at
com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2527) at
com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2680) at
com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2484) at
com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1858)
at
com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2079)
at
com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2013)
at
com.mysql.jdbc.PreparedStatement.executeLargeUpdate(PreparedStatement.java:5104)
at
com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1998)
at
org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:175)
... 18 more
One of the lines above:
Hibernate: create table users (id integer not null, goal integer not null, name varchar(255), total integer not null, primary key (id)) type=MyISAM
but after this, there is an exception which I don't understand. In mySql, there is no table created.
Thank you very much and a happy new year!
I am not sure, just follow documentation Hibernate_doc
Configuration cfg = new Configuration()
.addClass(com.andrei.User.class)
in this case hibernate will be search configuration for this class User.hbm.xml. Pay attention the config files should be placed near declared class.
instead of
conf.addAnnotatedClass(com.andrei.User.class);
About second question. Where do you situated the configuration file hibernate.cfg.xml ??
You should use (or implement) custom NamingStrategy class in order to map classname "User" to tablename "Users. See for details spring - hibernate 5 naming strategy configuration

Hibernate XML Mapping Exception

I'm trying to test the hibernate configuration of a project, but when I try to run the test it throws a MappinException saying that it does not known my entity, I checked the database and it is not creating the tables either, so my guess is that it is not reading the mapping files, but I checked that and the path is correct. And the package and class properties inside the mapping files is also correct (supposely).
Most of the questions I read are Annotation Focused, does anyone has an idea what's happening under the hood?
Thanks in advance
I have the following directory structure:
The hibernate.cfg.xml file it's like follows:
<hibernate-configuration>
<session-factory>
<!-- Hibernate Configuration -->
<property name="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="hibernate.hbm2ddl.auto">
update
</property>
<!-- Database Configuration -->
<property name="hibernate.connection.url">
jdbc:mysql://127.0.0.1:3306/library_management?createDatabaseIfNotExist=true
</property>
<property name="hibernate.connection.username">
root
</property>
<property name="hibernate.connection.password">
cetys
</property>
<!-- Class Mapping Files -->
<mapping resource="Hibernate.config/mapping/Book.hbm.xml"/>
<mapping resource="Hibernate.config/mapping/Classification.hbm.xml"/>
<mapping resource="Hibernate.config/mapping/Collection.hbm.xml"/>
<mapping resource="Hibernate.config/mapping/Loan.hbm.xml"/>
<mapping resource="Hibernate.config/mapping/NonExistentRegistry.hbm.xml"/>
</session-factory>
</hibernate-configuration>
The Loan mapping file is:
<hibernate-mapping package="com.cetys.cetyslibraryinventory.Core.DomainModels">
<class name="Loan" table="loan">
<meta attribute="class-description">
This class contains the basic information for a Loan
</meta>
<id name="id" column="loan_id" type="int"></id>
<many-to-one name="bookId" class="Book" unique="true"
column="book_id" cascade="all"/>
</class>
</hibernate-mapping>
The model:
package com.cetys.cetyslibraryinventory.Core.DomainModels;
//imports ommited
public class Loan implements Catalogable {
private int id;
private int book_id;
protected Loan () {
}
public Loan ( int id, int book_id ) {
this.id = id;
this.book_id = book_id;
}
// Getters and Setters Ommited
}
And when I try to run the following:
public class Program {
public static void main ( String[] args ) {
SessionFactory sessionFactory = null;
Session session = null;
Transaction tx = null;
try {
Configuration configuration = new Configuration();
configuration.configure( "hibernate.cfg.xml" );
ServiceRegistry serviceRegistry
= new StandardServiceRegistryBuilder().applySettings(
configuration.getProperties() ).build();
sessionFactory = configuration.
buildSessionFactory( serviceRegistry );
session = sessionFactory.openSession();
Loan ln = new Loan( 0, 0 );
tx = session.beginTransaction();
session.save( ln );
tx.commit();
} catch ( Exception e ) {
LOGGER.log( Level.SEVERE, e.getMessage(), e );
} finally {
if ( session != null ) {
session.close();
}
if ( sessionFactory != null ) {
sessionFactory.close();
}
}
}
}
Exception Error:
SEVERE: Unknown entity: com.cetys.cetyslibraryinventory.Core.DomainModels.Loan
org.hibernate.MappingException: Unknown entity: com.cetys.cetyslibraryinventory.Core.DomainModels.Loan
at org.hibernate.internal.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:776)
at org.hibernate.internal.SessionImpl.getEntityPersister(SessionImpl.java:1533)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:104)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:38)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177)
at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:32)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:682)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:674)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:669)
at com.cetys.cetyslibraryinventory.Program.main(Program.java:74)
Jun 08, 2016 10:04:41 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop
INFO: HHH10001008: Cleaning up connection pool [jdbc:mysql://127.0.0.1:3306/library_management?createDatabaseIfNotExist=true]

Hibernate not connecting with MySql

Stuck at this place I am new to hibernate and making a sample code after watching tutorial However I am stuck connecting hibernate with MySql.
Here is hibernate.cfg.xml placed in the source folder
<?xml version='1.0' encoding='utf-8'?>
<!-- ~ Hibernate, Relational Persistence for Idiomatic Java ~ ~ License:
GNU Lesser General Public License (LGPL), version 2.1 or later. ~ See the
lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. -->
<hibernate-configuration
xmlns="http://www.hibernate.org/xsd/hibernate-configuration"
xsi:schemaLocation="http://www.hibernate.org/xsd/hibernate-configuration
hibernate-configuration-4.0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/test</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<!-- JDBC connection pool (use the built-in) -->
<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.internal.NoCacheProvider
</property>
<property name="current_session_context_class">thread</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>
<mapping class="com.javapapers.UserDetails" />
</session-factory>
</hibernate-configuration>
And here is my HibernateTest.java file
package com.javapapers;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
UserDetails user=new UserDetails();
user.setUserId(1);
user.setUserName("Mannu");
System.out.println("Here");
SessionFactory sessionFactory=new Configuration().configure().buildSessionFactory();
System.out.println("Not even printed");
Session session=sessionFactory.openSession();
session.beginTransaction();
session.save(user);
session.getTransaction().commit();
}
}
Here is UserDetails.java
package com.javapapers;
import javax.persistence.Entity;
import javax.persistence.Id;
#Entity
public class UserDetails {
#Id
private int userId;
private String userName;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
And Here is Error Report
Here
Nov 11, 2015 2:23:03 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {5.0.2.Final}
Nov 11, 2015 2:23:03 PM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
Nov 11, 2015 2:23:03 PM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
Exception in thread "main" org.hibernate.internal.util.config.ConfigurationException: Unable to perform unmarshalling at line number 10 and column 56 in RESOURCE hibernate.cfg.xml. Message: cvc-elt.1: Cannot find the declaration of element 'hibernate-configuration'.
at org.hibernate.boot.cfgxml.internal.JaxbCfgProcessor.unmarshal(JaxbCfgProcessor.java:133)
at org.hibernate.boot.cfgxml.internal.JaxbCfgProcessor.unmarshal(JaxbCfgProcessor.java:65)
at org.hibernate.boot.cfgxml.internal.ConfigLoader.loadConfigXmlResource(ConfigLoader.java:57)
at org.hibernate.boot.registry.StandardServiceRegistryBuilder.configure(StandardServiceRegistryBuilder.java:163)
at org.hibernate.cfg.Configuration.configure(Configuration.java:259)
at org.hibernate.cfg.Configuration.configure(Configuration.java:245)
at com.javapapers.HibernateTest.main(HibernateTest.java:15)
Caused by: javax.xml.bind.UnmarshalException
- with linked exception:
[org.xml.sax.SAXParseException; lineNumber: 10; columnNumber: 56; cvc-elt.1: Cannot find the declaration of element 'hibernate-configuration'.]
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(UnmarshallerImpl.java:420)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:401)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:374)
at org.hibernate.boot.cfgxml.internal.JaxbCfgProcessor.unmarshal(JaxbCfgProcessor.java:126)
... 6 more
Caused by: org.xml.sax.SAXParseException; lineNumber: 10; columnNumber: 56; cvc-elt.1: Cannot find the declaration of element 'hibernate-configuration'.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:198)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:134)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:437)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:368)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:325)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleStartElement(XMLSchemaValidator.java:1906)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.startElement(XMLSchemaValidator.java:746)
at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.startElement(ValidatorHandlerImpl.java:570)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.ValidatingUnmarshaller.startElement(ValidatingUnmarshaller.java:86)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.InterningXmlVisitor.startElement(InterningXmlVisitor.java:60)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.StAXEventConnector.handleStartElement(StAXEventConnector.java:246)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.StAXEventConnector.bridge(StAXEventConnector.java:115)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:398)
... 8 more
Create SessionFactory like that. It worked at Hibernate 4.3.
Configuration configuration = new Configuration();
configuration.configure();
private static ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
private static SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
And it's total violation of factory pattern to do that in main. Make separate class for it.

After changing JDBC to hibernate the application runs very slow

Previously I used JDBC in my application and it was running very fast, but I have modified it to use Hibernate which made it too slow, especially when it needs to open a page that has a dropdown box in it. It takes much longer in compare to JDBC, to open this kind of pages.
If I try to access a table with foreign keys it takes much longer.
My server is GlassFish and I am usingfollowing version of hibernate.
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.1.10.Final</version>
<type>jar</type>
</dependency>
The questions are why is it to slow in compare to JDBC and do I need to have the following lin before each session.beginTransaction() ?
session = HibernateUtil.getSessionFactory().openSession();
Take the following one as an example, it has a dropdown box that need to be populated once the page is opened.
HibernateUtil.java
package com.myproject.util;
import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
public class HibernateUtil {
private static SessionFactory sessionFactory;
private static ServiceRegistry serviceRegistry;
private static SessionFactory configureSessionFactory() {
try {
System.out.println("1");
Configuration configuration = new Configuration();
configuration.configure();
serviceRegistry = new
ServiceRegistryBuilder()
.applySettings(configuration.getProperties())
.buildServiceRegistry();
System.out.println("2");
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
System.out.println("3");
return sessionFactory;
} catch (HibernateException e) {
System.out.append("** Exception in SessionFactory **");
e.printStackTrace();
}
return sessionFactory;
}
public static SessionFactory getSessionFactory() {
return configureSessionFactory();
}
}
MyClassModel.java
public class MyClassModel extends HibernateUtil {
private Session session;
public Map populatedropdownList() {
Map map = new HashMap();
session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
List<MyListResult> temp = null;
try{
temp = retrieveItems();
System.err.println("size:" + temp.size());
for(int i=0;i<temp.size();i++){
map.put(temp.get(i).getId(),temp.get(i).getName());
}
session.getTransaction().commit();
session.close();
return map;
}catch(Exception e){
e.printStackTrace();
}
return map;
}
private List <MyListResult> retrieveItems(){
Criteria criteria = session.createCriteria(MyTable.class, "MyTable");
ProjectionList pl = Projections.projectionList();
pl.add(Projections.property("MyTable.id").as("id"));
pl.add(Projections.property("MyTable.name").as("name"));
criteria.setProjection(pl);
criteria.setResultTransformer(new
AliasToBeanResultTransformer(MyListResult.class));
return criteria.list();
}
MyListResult.java
public class MyListResult implements Serializable {
private int id;
private String Name;
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;
}
}
Hibernate.cfg.xml
<?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://localhost:3306/MyDatabase
</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>
<!-- JDBC connection pool (use the built-in) -->
<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>
<!-- 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>
<mapping class="com.MyProject.MyTable" />
</session-factory>
</hibernate-configuration>
Console is as following
INFO: in myform
INFO: 1
INFO: HHH000043: Configuring from resource: /hibernate.cfg.xml
INFO: HHH000040: Configuration resource: /hibernate.cfg.xml
INFO: HHH000041: Configured SessionFactory: null
INFO: 2
INFO: HHH000402: Using Hibernate built-in connection pool (not for production use!)
INFO: HHH000115: Hibernate connection pool size: 1
INFO: HHH000006: Autocommit mode: false
INFO: HHH000401: using driver [com.mysql.jdbc.Driver] at URL
[jdbc:mysql://localhost:3306/MyDatabase]
INFO: HHH000046: Connection properties: {user=root, password=****}
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
INFO: HHH000399: Using default transaction strategy (direct JDBC transactions)
INFO: HHH000397: Using ASTQueryTranslatorFactory
INFO: HHH000228: Running hbm2ddl schema update
INFO: HHH000102: Fetching database metadata
INFO: HHH000396: Updating schema
INFO: HHH000261: Table found: MyDatabase.MyTable
INFO: HHH000037: Columns: [id, name, age, xx, yy]
INFO: HHH000126: Indexes: [primary]
INFO: HHH000232: Schema update complete
INFO: Hibernate: select this_.id as y0_, this_.name as y1_ from MyTable this_
SEVERE: size:4
Usually in the application you shouldn't build the session factory each time when you need the session. That's what actually needed by application to use the hibernate. If you want to manage the session manually then you write the HibernateUtil making it singleton. Initially, build the session factory in the static initializer block
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<>();
private static SessionFactory sessionFactory;
static {
try {
sessionFactory = configureSessionFactory();
} catch (Exception e) {
System.err.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
private HibernateUtil() {
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static Session getSession() throws HibernateException {
Session session = threadLocal.get();
if (session == null || !session.isOpen()) {
if (sessionFactory == null) {
rebuildSessionFactory();
}
session = (sessionFactory != null) ? sessionFactory.openSession() : null;
threadLocal.set(session);
}
return session;
}
public static void rebuildSessionFactory() {
try {
sessionFactory = configureSessionFactory();
} catch (Exception e) {
System.err.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
public static void closeSession() throws HibernateException {
Session session = (Session) threadLocal.get();
threadLocal.set(null);
if (session != null) {
session.close();
}
}
think that's enough addition to your code to run your application.
While I don't have any direct experience with Hibernate, I do with NHibernate, which is modeled after the Java version, so this should still be correct...
Building up the SessionFactory takes time, all the more so since, if I'm reading the configuration right, you're having it check for schema changes between your models and the database when it does start.
What you should do instead is create the SessionFactory once on startup (or upon the first use of data access, depending on when you want to pay the cost of setting up Hibernate) and use that through the lifetime of your app.
What I tend to do is something roughly like this (rough psuedocode, since my Java is rusty):
Session getSession()
{
if(sessionFactory == null)
buildSessionFactory()
return sessionFactory.OpenSession()
}
(Of course this doesn't take into account any possible race conditions with threading). This should hopefully see a rather large performance boost. Keep in mind that ORMs are almost never as fast as hand-coded SQL due to the additional mapping layers, but it's a trade off between performance and ease of coding.

Categories

Resources