Why Hibernate SchemaUpdate is creating new field instead of updating? - java

I am trying to update the existing schema programmatically using SchemaUpdate. I changed the name of the existing field name in specific table and then,
I am creating the hibernate configuration object and adding the changed hbm.xml files into the configuration object.
But when I said SchemaUpdate.execute(true,true) it is creating the new field in the table instead of updating.
Here is my code:
Configuration hibConfiguration = new Configuration();
hibConfiguration.configure(configFileDoc);
hibConfiguration.addDocument(doc1);
hibConfiguration.addDocument(doc2);
hibConfiguration.buildMappings();
SchemaUpdate schemaUpdate = new SchemaUpdate(hibConfiguration);
schemaUpdate.execute(true, true);
following is my cfg.xml file:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">passwrd</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhot:3306/testSchema</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<property name="javax.persistence.validation.mode">none</property>
<property name="hibernate.temp.use_jdbc_metadata_defaults">false</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.default_entity_mode">dynamic-map</property>
</session-factory>
</hibernate-configuration>
and this is my hbm.xml file for table to update:
<?xml version="1.0" encoding="UTF-8"?><hibernate-mapping>
<class entity-name="testTable2">
<id column="id" name="id" type="java.lang.Long">
<generator class="identity"/>
</id>
<property column="testTable1Id" length="20" name="testTable1Id" type="java.lang.Long"/>
<property column="doubleColumnj" length="20" name="doubleColumnj" type="java.lang.Double"/>
</class>
</hibernate-mapping>

Hibernate does not do version control on tables. It has no way of determining that the field was renamed. So when it compares the existing mapping to the database, all it is able to determine is there is a mapped column which did not exist before.
It also does not drop unmapped columns in order to be able to support legacy databases, or perhaps multiple hibernate entities providing different views of the same table.

Related

Could not parse mapping document from resource Books.hbm.xml

Why am i getting hibernate.invalidmappingexception when i try to save an object in database with hibernate..
books.hbm.xml (Inside the resource folder)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Books" table="books">
<id name="id">
<generator class="increment"></generator>
</id>
<property name="name"></property>
<property name="author"></property>
<property name="count"></property>
<property name="description"></property>
</class>
</hibernate-mapping>
Hibernate.cfg.xml:
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect"> org.hibernate.dialect.MySQLDialect </property>
<property name="hibernate.connection.driver_class"> com.mysql.jdbc.Driver </property>
<property name="hibernate.connection.url"> jdbc:mysql://localhost/cybage </property>
<property name="hibernate.connection.username"> root </property>
<property name="hibernate.connection.password"> yoga </property>
<mapping resource="Books.hbm.xml"/>
</session-factory>
</hibernate-configuration>
And My project structure is:
I have placed the mapping files BOOKS.hbm.xml in resource folder and the Hibernate.cfg.xml in the META/classes folder
You need to specify a full class name with a package in the books.hbm.xml
<class name="pack.Books" table="books">
....
</class>
You need to have the resources folder in the main folder to have all files in the WEB-INF/classes, after building a war. WEB-INF/classes will be in the class path by default.
You have hibernate.cfg.xml and user.hbm.xml in the classes folder — move all xml from the classes to the resources.
Try to replace this:
<mapping resource="Books.hbm.xml"/>
With:
<mapping resource="resources/Books.hbm.xml"/>
Adding the right path.
You need to provide correct mapping path of hbm file in Hibernate.cfg.xml
so Just replace to
<mapping resource="resources/Books.hbm.xml"/>
Because your hbm file is located in resources folder so you need to provide same path.

Cannot modify hibernate settings

I created hibernate.cfg.xml and UserDataFromDb.hbm.xml and tried to put it in a correct place. First time there was exception like "Cannot find hibernate.cfg.xml", but after several replacement correct place was found. New exception was (with except of lots of other trace):
Caused by: org.hibernate.HibernateException: Enum class not found
Caused by: java.lang.ClassNotFoundException: net.codejava.hibernate.Gender
It is ok, because I've forgotten to change tutorial sample code and print my class name. I've fixed this problem, so, now there are no mentions about class Gender in UserDataFromDb.hbm.xml. Problem is certainly the same.
I've replaced both UserDataFromDb.hbm.xml and hibernate.cfg.xml to desktop and even renamed them. So, no there are no either UserDataFromDb.hbm.xml or hibernate.cfg.xml files on my computer (instead of them -- UserData11FromDb.hbm.xml and hiber111nate.cfg.xml on desktop). Exception are still the same:
Caused by: org.hibernate.HibernateException: Enum class not found
Caused by: java.lang.ClassNotFoundException: net.codejava.hibernate.Gender
though neither Gender class nor even configuration and mapping files exist on computer.
Rebooting computer makes no effect.
OS Windows 7, Hibernate 4.3.6
Config file:
`
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>
<!-- Assume test is the database name -->
<property name="hibernate.connection.url">
jdbc:mysql://localhost/abusefinder
</property>
<property name="hibernate.connection.username">
root
</property>
<property name="hibernate.connection.password">
</property>
<!-- List of XML mapping files -->
<mapping resource="UserDataFromDb.hbm.xml" />
</session-factory>
</hibernate-configuration>
mapping:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="UserDataFromDb" table="user_history">
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<list name="operations" cascade="all">
<key column="user_id"/>
<list-index column="idx"/>
<one-to-many class="Operation"/>
</list>
<property name="maxOpersPerWeek" column="max_opers_per_week" type="int"/>
<property name="currentOpersPerWeek" column="current_opers_per_week" type="int"/>
<property name="lastWeekFirstOperationTime" column="last_week_first_operation_time" type="long"/>
<property name="addTotal" column="add_total" type="long"/>
<property name="getTotal" column="get_total" type="long"/>
<property name="addOpers" column="add_opers" type="int"/>
<property name="getOpers" column="get_opers" type="int"/>
</class>
<class name="Operation" table="operations">
<id name="operId" type="int" column="oper_id">
<generator class="native"/>
</id>
<property name="userId" column="user_id" type="int"/>
<property name="sum" column="sum" type="long"/>
<property name="time" column="time" type="long"/>
<property name="type" column="type">
<type name="org.hibernate.type.EnumType">
<param name="enumClass">databaseaccess.Type</param>
<param name="useNamed">true</param>
</type>
</property>
</class>
</hibernate-mapping>
Project -> clean
project -> build

Hibernate Reverse Engineering Create Set (Composite Key)

I'm having trouble getting Hibernate to correctly reverse engineer a MySQL database into a Java Class.
I have 3 tables:
departments (pk = dept_no)
employees (pk = emp_no)
dept_emp (composite pks dept_no and emp_no)
I am trying to modify the Hibernate Reverse Engineering file to force the DeptEmp Java class that is generated to link a single department to a set of employees within that department, but I keep getting the same error, even though I have declared a name attribute for the set:
org.hibernate.MappingException: Could not configure overrides from file: C:\lib\workspace\Hibernate Analysis 2\resources\hibernate.reveng.xml
Could not configure overrides from file: C:\lib\workspace\Hibernate Analysis 2\resources\hibernate.reveng.xml
org.hibernate.MappingException: Could not configure overrides from file: C:\lib\workspace\Hibernate Analysis 2\resources\hibernate.reveng.xml
Could not configure overrides from file: C:\lib\workspace\Hibernate Analysis 2\resources\hibernate.reveng.xml
org.hibernate.MappingException: invalid override definition
invalid override definition
org.xml.sax.SAXParseException; lineNumber: 10; columnNumber: 88; Attribute "name" must be declared for element type "set".
Attribute "name" must be declared for element type "set".
My Reverse Engineering File:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-reverse-engineering PUBLIC "-//Hibernate/Hibernate Reverse Engineering DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-reverse-engineering-3.0.dtd" >
<hibernate-reverse-engineering>
<table-filter match-catalog="employees" match-name="departments" />
<table-filter match-catalog="employees" match-name="employees" />
<table-filter match-catalog="employees" match-name="dept_emp" />
<table name="dept_emp" class="com.DeptEmp">
<set name="employeesSet" table="employees" inverse="true" lazy="true" fetch="select">
<key>
<column name="dept_no" ></column>
</key>
<one-to-many class="com.Employees"></one-to-many>
</set>
</table>
</hibernate-reverse-engineering>
My Hibernate Config:
<?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.url">jdbc:mysql://localhost:3306/employees</property>
<property name="hibernate.connection.username">****</property>
<property name="hibernate.connection.password">****</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.default_catalog">employees</property>
<property name="connection.pool_size">20</property>
<property name="current_session_context_class">thread</property>
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="use_sql_comments">true</property>
</session-factory>
</hibernate-configuration>

Hibernate auto create database

I have a Java EE Hibernate project, and I'm using MySQL as a database.
I want that when I first time run the project, it will create the database automatically.
This is my hibernate.cnf.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="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost/InternetProject</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>
<property name="connection.pool_size">10</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="show_sql">true</property>
<mapping class="entities.Business" />
<mapping class="entities.Coupon" />
<mapping class="entities.User" />
<mapping class="entities.LastLogin" />
</session-factory>
</hibernate-configuration>
When I first time run this project on another computer, how can I make the database InternetProject to be created?
According to the config file, it might already do it and I'm not aware to it.
Thanks in advance.
<property name="hibernate.hbm2ddl.auto">create</property>
will create tables. But it will not create database. Change the connection url to generate the database.
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost/InternetProject?createDatabaseIfNotExist=true</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>
<property name="connection.pool_size">10</property>
Update : character encoding when creating database
<property name="connection.url">
jdbc:mysql://localhost/InternetProject?createDatabaseIfNotExist=true&useUnicode=yes&characterEncoding=UTF-8
</property>
<property name="hibernate.hbm2ddl.auto">create</property>
will do
Hibernate will not create the database for you, only the tables. To create the database you need to tell MySQL to create it if it does'nt already exist by adding a parameter to the URL. E.g.:
jdbc:mysql://db:3306/mydatabase?createDatabaseIfNotExist=true
There are multiple option for auto property.
create - It creates new tables corresponding mapping or annotation. It drops existing tables and data.
update - It keeps existing data and tables. It updates schema. here we have to take care contrants.
create-drop - It is same like create but once session gets closed it drops everything.
validate - it validates or matches schema with map or annotation. It's valid for Production environment.
<!-- create create-drop validate update -->
<property name="hbm2ddl.auto">update</property>
I hope it helps.

How can I stop auto Scheme creation?

If it is duplicate, my apology. I could not find an answer for my question.
I just start Hibernate. I have an issue is every time the program automatically delete the old shceme and creates new when it is running. For example, If I want to add records into database, I could not do it because the scheme will be recreate, so the histories will be deleted.
Here is my hbm.xml mapping file:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 22-Oct-2013 1:39:31 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="net.ys.hibernate.Equip" table="EQUIP">
<id name="id" type="int">
<column name="ID" />
<generator class="native" />
</id>
<property name="dis" type="java.lang.String" column="dis" />
<property name="ref" type="java.lang.String" column="ref" />
<property name="type" type="java.lang.String" column="type" />
</class>
</hibernate-mapping>
hibernate.cfg.xml configuration 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>
<!-- hibernate dialect -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">pw</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/explorer_DB?useUnicode=true&characterEncoding=GBK</property>
<property name="hibernate.connection.username">username</property>
<property name="hibernate.default_schema">explorer_DB</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Automatic schema creation(begin) -->
<property name="hibernate.hbm2ddl.auto">create</property>
<!-- Simple memory-only cache -->
<property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- mapping files with external dependencies -->
<mapping resource="net/ys/hibernate/Equip.hbm.xml"/>
</session-factory>
</hibernate-configuration>
And addEquip method:
public Integer addEquip(String dis, String ref, String type){
Session session = sessionFactory.openSession();
currentSession = sessionFactory.getCurrentSession();
Transaction tx = null;
Integer equipID = null;
try {
tx = currentSession.beginTransaction(); //start a transaction
Equip equip = new Equip(dis,ref,type);
equipID = (Integer)currentSession.save(equip);
tx.commit();
} catch (HibernateException e) {
if(tx!=null) tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
return equipID;
}
}
could someone help me to solve this issue? I just don't understand how to use getCurrentSession(), probably I am wrong in this point. Could you explain how hibernate works when we call getCurrentSession() for me? I really appreciate it.
Thank you so much
Change this property in your hibernate.cfg.xml file
current configuration
<property name="hibernate.hbm2ddl.auto">create</property>
to
<property name="hibernate.hbm2ddl.auto">none</property>
if no change required in database use.
<property name="hibernate.hbm2ddl.auto">validate</property>
More on this please refer this link
Hibernate hbm2ddl.auto possible values and what they do?

Categories