OGM and ORM named queries in xml file - java

My application contains both ORM and OGM. For ORM I was wrote some named queries in xyz.hbm.xml. But while using OGM those queries caused for exception. I am using OGM 4.1.3.Final version. Please help someone.
example.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">
<!-- Generated Jan 1, 2015 1:53:57 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="mkcl.os.apps.edumiss.model.student.Admission" table="ADMISSION">
<id name="id" type="java.lang.String">
<column name="ADMISSION_ID" />
<generator class="uuid" />
</id>
<property name="studentId">
<column name="STUDENTID" />
</property>
<property name="schoolId">
<column name="SCHOOL_ID" />
</property>
<property name="academicYearId" type="int">
<column name="ACADEMICYEARID" />
</property>
<property name="sectionRollNumber" type="int">
<column name="SECTIONROLLNUMBER" />
</property>
<property name="admissionDate" type="java.util.Date">
<column name="ADMISSIONDATE" />
</property>
<property name="schoolLeavingDate" type="java.util.Date">
<column name="SCHOOL_LEAVING_DATE" />
</property>
<property name="standardId" type="short">
<column name="STANDARDID" />
</property>
<property name="standardName" type="java.lang.String">
<column name="STANDARD_NAME" />
</property>
<property name="sectionId">
<column name="SECTION_ID" />
</property>
<property name="sectionName">
<column name="SECTION_NAME" />
</property>
<property name="reasonForLeaving">
<column name="REASON_FOR_LEAVING" />
</property>
<property name="streamId" type="short">
<column name="STREAM_ID" />
</property>
<property name="streamName" type="java.lang.String">
<column name="STREAM_NAME" />
</property>
<property name="admissionType" column="ADMISSION_TYPE">
<type name="org.hibernate.type.EnumType">
<param name="useNamed"></param>
<param name="enumClass">mkcl.os.apps.edumiss.model.student.AdmissionType</param>
</type>
</property>
<property name="createdBy" type="java.lang.String">
<column name="CREATED_BY" />
</property>
<property name="createOn" type="java.util.Date">
<column name="CREATED_ON" />
</property>
<property name="modifiedBy" type="java.lang.String">
<column name="MODIFIED_BY" />
</property>
<property name="lastModified" type="java.util.Date">
<column name="LAST_MODIFIED" />
</property>
<property name="patternId" type="integer">
<column name="PATTERN_ID"></column>
</property>
</class>
<sql-query name="getAdmissionForAcademicYear">
<return alias="admission" class="mkcl.os.apps.edumiss.model.student.Admission"></return>
<![CDATA[
SELECT
{admission.*}
FROM
ADMISSION admission
INNER JOIN STUDENT s
ON
s.CURRENT_ADMISSION_ID = admission.ADMISSION_ID
WHERE
admission.STUDENTID = :mkclIdentificationNumber
AND
admission.ACADEMICYEARID = :academicYearId
]]>
</sql-query>
</hibernate-mapping>
this throws
java.lang.IncompatibleClassChangeError: class org.objectweb.asm.tree.ClassNode has interface org.objectweb.asm.ClassVisitor as super class
if I am removing above query from hbm file then it worked fine. But I have to keep those queries in .hbm.xml file as it is.

That query is for a relational database, so you don't need the OGM for that.
Why do you want to run an SQL query against OGM, which is for NoSQL?
The default hibernate.archive.autodetection property value is class,hbm, so make sure you set it to class in the persistence.xml file that's associated to the OGM EntityManagerFactory. You do have two separate persistence.xml configurations (one for ORM and one for OGM), right?

according to current version of OGM(5.0) feature document:
Model can not possible to share between OGM and ORM together and this will projected to resolve in next version of OGM.
ORM classes can try to parse the .hbm.xml file and find the named queries which having the syntax of mongo query. so while reading the file OGM unable to parse the syntax of SQL named query and throws an error so I have only way to shift the all the queries into another hbm whose wntry will not be present in nosql_hibernate.xml file so OGM will not parse and my code will run fast else till this feature not support shift to another framework.

Related

Hibernate primary key violation on two server instances

I have an application which is running on two servers and both these servers access the same database via Hibernate.
The issue here is when these two applications process large set of data and trying to insert to the same table. There is a primary key violation happens. And from the things I have noticed, hibernate seems to buffer some number of primary key ids. eg. If server A insert data into id 100 and at the same time server B will be inserting to id 200 or so. I guess this issue is related to above mentioned scenario. Following is my hibernate properties
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/dbtest?autoReconnect=true</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">password</property>
<!-- <property name="hibernate.show_sql">true</property>-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!--
<property name="hibernate.hbm2ddl.auto">update</property>
-->
<property name="hibernate.use_sql_comments">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.connection.zeroDateTimeBehavior">convertToNull</property>
<property name="hibernate.connection.isolation">2</property>
<property name="hibernate.default_schema">dbtest</property>
<property name="hibernate.jdbc.batch_size">50</property>
<!--c3po connection pooling -->
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.timeout">300</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.idle_test_period">3000</property>
This is the entity which is failing
<?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 Sep 3, 2014 4:38:39 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.test.dto.AdditionalContacts" table="additional_contacts"
entity-name="additionalcontacts">
<id name="contactId" type="java.lang.Integer" column="contactId">
<generator class="increment" />
</id>
<property name="contactGuid" type="java.lang.String">
<column name="contactGuid" />
</property>
<property name="contactName" type="java.lang.String">
<column name="contactName" />
</property>
<property name="salutation" type="java.lang.String">
<column name="salutation" />
</property>
<property name="EmailAddress" type="java.lang.String">
<column name="email" />
</property>
<property name="includeInEmails" type="java.lang.Boolean">
<column name="includeInEmails" />
</property>
<property name="Website" type="java.lang.String">
<column name="website" />
</property>
<property name="city" type="java.lang.String">
<column name="city" />
</property>
<property name="state" type="java.lang.String">
<column name="state" />
</property>
<property name="postCode" type="java.lang.String">
<column name="postCode" />
</property>
<property name="country" type="java.lang.String">
<column name="country" />
</property>
<property name="street" type="java.lang.String">
<column name="street" />
</property>
<property name="streetLine1" type="java.lang.String">
<column name="streetLine1" />
</property>
<property name="streetLine2" type="java.lang.String">
<column name="streetLine2" />
</property>
<property name="streetLine3" type="java.lang.String">
<column name="streetLine3" />
</property>
<property name="streetLine4" type="java.lang.String">
<column name="streetLine4" />
</property>
<property name="phone1" type="java.lang.String">
<column name="phone1" />
</property>
<property name="phone2" type="java.lang.String">
<column name="phone2" />
</property>
<property name="phone3" type="java.lang.String">
<column name="phone3" />
</property>
<property name="fax" type="java.lang.String">
<column name="fax" />
</property>
<property name="location" type="java.lang.String">
<column name="location" />
</property>
<property access="field" column="createDate" insert="true"
name="createDate" update="false" />
<property access="field" column="modifyDate" insert="true"
name="modifyDate" update="true" />
</class>
</hibernate-mapping>
And following is the entity which uses above entity
<?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 Sep 3, 2014 4:38:39 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.test.dto.Contacts" table="contact"
entity-name="contact">
<id name="cGuid" type="java.lang.String">
<column name="contactGuid" />
</id>
<property name="org" type="java.lang.Integer">
<column name="org" />
</property>
<property name="Name" type="java.lang.String">
<column name="name" />
</property>
<property name="FirstName" type="java.lang.String">
<column name="firstName" />
</property>
<property name="LastName" type="java.lang.String">
<column name="lastName" />
</property>
<property name="abn" type="java.lang.String">
<column name="abn" />
</property>
<property name="active" type="java.lang.Boolean">
<column name="active" />
</property>
<property access="field" column="createDate" insert="true"
name="createDate" update="false" />
<property access="field" column="modifyDate" insert="true"
name="modifyDate" update="true" />
<bag name="additionalContactList" table="additional_contact" lazy="false" inverse="true"
cascade="all">
<key>
<column name="contactGuid" not-null="true" />
</key>
<one-to-many entity-name="additionalcontacts"
class="com.test.dto.AdditionalContact" />
</bag>
</class>
</hibernate-mapping>
This one is failing on
cascade="all"
You need to use AUTO_INCREMENT. This way MySQL will manage the creation of IDs, so the servers won't have to synchronize. Change the DB column to be AUTO_INCREMENT. In Hibernate change the generator type to native.
Other alternatives would be to use UUID as the primary key.
Newer versions of Hibernate have other generators that can be used that are better than native.

How to map an auto increment field in hibernate?

Please have a look at the below XML code
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- Generated Feb 17, 2015 10:01:43 PM by Hibernate Tools 4.3.1 -->
<hibernate-mapping>
<class name="model.main.Family" table="family" catalog="****" optimistic-lock="version">
<id name="idFamily" type="int">
<column name="idFamily" />
<generator class="assigned" />
</id>
<many-to-one name="employee" class="model.main.Employee" fetch="select">
<column name="idEmployee" not-null="true" />
</many-to-one>
<property name="firstName" type="string">
<column name="FirstName" length="45" />
</property>
<property name="middleName" type="string">
<column name="MiddleName" length="45" />
</property>
<property name="lastName" type="string">
<column name="LastName" length="45" />
</property>
<property name="dob" type="date">
<column name="DOB" length="10" />
</property>
<property name="passportNumber" type="string">
<column name="PassportNumber" length="45" not-null="true" />
</property>
<property name="dateLeft" type="date">
<column name="DateLeft" length="10" />
</property>
<property name="lastUpdated" type="timestamp">
<column name="LastUpdated" length="19" not-null="true" />
</property>
<set name="visas" table="visa" inverse="true" lazy="true" fetch="select">
<key>
<column name="idFamily" />
</key>
<one-to-many class="model.main.Visa" />
</set>
</class>
</hibernate-mapping>
It is the Hibernate mapping class of my database table Family. We create the database separately using MySQL Work bench and then generate the mapping classes. We auto generated the mapping files using netbeans as mentioned in "Generating Hibernate Mapping Files and Java Classes" section of netbeans tutorial.
Now we have a problem. That is, we changed the primary key (idFamily) of our table Family to an auto generated field inside MySQL. Now, how can we change the above hibernate code so it identifies the idFamily as an auto generated one?
The other question is, manually editing one mapping class without regenerating all the mappings via a tool can "break" the system? For an example, like messing up with relationships?
In Annotation It work for me as
#GeneratedValue(strategy= GenerationType.IDENTITY)
for you hope it works
<generated-value strategy="IDENTITY" />
You're looking for an identity column. That indicates that the column value is auto-generated as an identity for the row by the RDBMS.
<generator class="identity" />
See the these Hibernate docs for more information. According to it:
Identity
supports identity columns in DB2, MySQL, MS SQL Server, Sybase and HypersonicSQL. The returned identifier is of type long, short or int.
Just replace your generator class to increment it will treat it as autoincrement
<generator class="increment"/>
<?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.tech.spring4.model.User" table="Customer">
<id name="id" type="long">
<column name="USERID" unique="true"/>
<generator class="increment"/>
</id>
<property name="username"><column name="username" length="30" not-null="true"></column></property>
<property name="email"><column name="email" length="100" not-null="true"></column></property>
<property name="address"><column name="address" length="100" not-null="true"></column></property>
</class>
</hibernate-mapping>

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 not Loading a class

I have a class Auction that contains a Class Item and Users but when I am getting the class, the class item and Users are not being loaded.
Auction Class 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 Dec 28, 2010 9:14:12 PM by Hibernate Tools 3.4.0.Beta1 -->
<hibernate-mapping>
<class name="com.BiddingSystem.Models.Auction" table="AUCTION">
<id name="AuctionId" type="long">
<column name="AUCTIONID" />
<generator class="native" />
</id>
<property name="StartTime" type="java.util.Date">
<column name="STARTTIME" />
</property>
<property name="EndTime" type="java.util.Date">
<column name="ENDTIME" />
</property>
<property name="StartingBid" type="long">
<column name="STARTINGBID" />
</property>
<property name="MinIncrement" type="long">
<column name="MININCREMENT" />
</property>
<many-to-one name="CurrentItem" class="com.BiddingSystem.Models.Item" fetch="join" cascade="all">
<column name="ItemId" />
</many-to-one>
<property name="AuctionStatus" type="java.lang.String">
<column name="AUCTIONSTATUS" />
</property>
<property name="BestBid" type="long">
<column name="BESTBID" />
</property>
<many-to-one name="User" class="com.BiddingSystem.Models.Users" fetch="join">
<column name="UserId" />
</many-to-one>
</class>
</hibernate-mapping>
When I am doing this:
Query query=session.createQuery("from Auction where UserId="+UserId);
List <Auction> AllAuctions= new LinkedList<Auction>(query.list());
The Users and Item are null
#ManyToOne(fetch=FetchType.EAGER) would be the annotation based configuration element you are missing. Please refer to the manual to see how to configure this by XML.

hibernate cascading delete, why not one delete on the foreign key?

I'm wondering why hibernate generates 1 delete per entity on a child table
instead of using one delete on the foreign key
Here's the hibernate.cfg.xml (No i's not the next SO :-t
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.url">jdbc:hsqldb:file:testdb;shutdown=true</property>
<property name="hibernate.connection.driver_class">org.hsqldb.jdbcDriver</property>
<property name="hibernate.connection.username">sa</property>
<property name="hibernate.connection.password"></property>
<property name="hibernate.connection.pool_size">0</property>
<property name="hibernate.dialect">org.hibernate.dialect.HSQLDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hbm2ddl.auto">auto</property>
<mapping file="entities/Question.hbm.xml"/>
<mapping file="entities/Answer.hbm.xml"/>
</session-factory>
Question.hbm.xml
<hibernate-mapping>
<class name="entities.Question">
<id name="id">
<generator class="native" />
</id>
<property name="title" not-null="true">
</property>
<property name="question" type="text" not-null="true">
</property>
<bag name="answers" inverse="true" cascade="all,delete-orphan" >
<key>
<column name="questionId" index="answer_questionId_idx" not-null="true"/>
</key>
<one-to-many class="entities.Answer" />
</bag>
<property name="created" update="false" >
<column name="created" not-null="true" index="answer_created_idx"></column>
</property>
<property name="lastUpdated">
<column name="lastUpdated" not-null="true" index="answer_lastUpdated_idx"></column>
</property>
</class>
</hibernate-mapping>
Answer.hbm.xml
<hibernate-mapping>
<class name="entities.Answer">
<id name="id">
<generator class="native" />
</id>
<property name="answer" type="text" not-null="true">
</property>
<property name="created" update="false" >
<column not-null="true" name="created" index="question_created_idx"></column>
</property>
<property name="lastUpdated" >
<column name="lastUpdated" not-null="true" index="question_lastUpdated_idx"></column>
</property>
<many-to-one name="question" column="questionId" not-null="true" update="false">
</many-to-one>
</class>
</hibernate-mapping>
There's 1 Question and 2 answers in my database, this test code:
Session session = factory.openSession();
Transaction t = session.beginTransaction();
Question q = (Question) session.load(Question.class,1);
session.delete(q);
t.commit();
session.close();
I would expect it to generate SQL like,
select .... from Questions where id = 1;
delete from Answers where questionId=1;
delete from Question where id=1;
I.e., just issue one delete to do the cascading delete on Answers,
instead it's loading all the answers and issuing one delete per answer, like:
select
question0_.id as id0_0_,
question0_.title as title0_0_,
question0_.question as question0_0_,
question0_.created as created0_0_,
question0_.lastUpdated as lastUpda5_0_0_
from
Question question0_
where
question0_.id=?
select
answers0_.questionId as questionId0_1_,
answers0_.id as id1_,
answers0_.id as id1_0_,
answers0_.answer as answer1_0_,
answers0_.created as created1_0_,
answers0_.lastUpdated as lastUpda4_1_0_,
answers0_.questionId as questionId1_0_
from
Answer answers0_
where
answers0_.questionId=?
delete from Answer where id=?
delete from Answer where id=?
delete from Question where id=?
How come, and is there anything I can do about it ?
Edit, in response to Nate Zaugg, I can get the db to do the cascading delete by setting on-delete="cascade" on the one-to-many key mapping, i'm more wondering why hibernate does what it does and not does one delete on the Answers table, and wheter threre's something wrong with my mappings.
Can you not configure your DMBS to do cascading deletes on relationships? It's really easy to do.
Edit: Try this <one-to-many class="entities.Answer" lazy="false" cascade="all" />

Categories