Hibernate one-to-one mapping updating instead of inserting and throwing StaleStateException - java

I am trying to do a one-to-one mapping using hibernate to insert some info into the DB but every time I try I get this error.
Caused by: org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:85)
at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:70)
at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:90)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:268)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:185)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1217)
at org.springframework.orm.hibernate3.SpringSessionSynchronization.beforeCommit(SpringSessionSynchronization.java:145)
... 12 more
Here is my client.hbm.xml file.
<hibernate-mapping>
<class name="register.Client" table="client" lazy="false">
<id name="clientId" type="string" column="CLIENT_ID"
length="255">
<generator class="increment"></generator>
</id>
<property name="address" type="string" column="ADDRESS"
length="255" />
<property name="email" type="string" column="EMAIL"
length="255" />
<property name="username" type="string" column="USERNAME"
unique="true">
</property>
<!-- Associations -->
<!-- bi-directional one-to-one association to Login -->
<one-to-one name="login" class="login.UsrPwd" lazy="false"
outer-join="auto" />
</hibernate-mapping>
Here is my login.hbm.xml file
<hibernate-mapping>
<class name="login.UsrPwd" table="login">
<id name="username" type="string" column="USER_NAME"> </id>
<property name="password" column="PASSWORD" type="string"/>
<property name="type" column="TYPE_ID" type="int"></property>
<one-to-one name="consultantInfo" class="register.ConsultantInfo"
cascade="all" />
<!-- bi-directional one-to-one association to Client -->
<one-to-one name="client" class="register.Client" cascade="all"/>
</class>
</hibernate-mapping>
when I run my function to add the info to the data base this is the SQL I get.
Hibernate: insert into login (PASSWORD, TYPE_ID, USER_NAME) values (?, ?, ?)
Hibernate: update client set ADDRESS=?, EMAIL=?, USERNAME=? where CLIENT_ID=?
I don't think the second one is supposed to be update because the row doesn't exist yet and that is why it is throwing the exception I am getting. I have no idea why it is doing this any help would be appreciated.
If you need any more info just let me know an I can provide it

Related

Generating DDL from hibernate mapping file

The following hibernate mapping file generates the java class and the DEPARTMENT table as expected but it doesn't create the DPT_TEACHERS table in the DB, why not ?
<hibernate-mapping>
<class name="hibernate.Department" table="DEPARTMENT">
<id name="id" column="ID">
<generator class="native"/>
</id>
<property name="subject" column="SUBJECT" type="string"/>
<set name="teachers" table="DPT_TEACHERS">
<key column="ID"/>
<one-to-many class="hibernate.Teacher"/>
</set>
</class>
</hibernate-mapping>
You need to add property
hibernate.hbm2ddl.auto
with your database connection properties in your hibernate.cfg.xml to create schema automatically.
<property name="hibernate.hbm2ddl.auto">create</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost/Test?createDatabaseIfNotExist=true</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>
<property name="connection.pool_size">10</property>
table="DPT_TEACHERS" is not required. There is no need for another table to create a 1:N relationship. key column="ID" is confusing, it should be key column="TEACHER_ID" so it can be added in Teacher table as a 1:N relationship

Hibernate Mapping - Join of two table to one flat class

I have two tables: patient_data and patient_diagnosis
Patient_data contains personal data of patient like: pid (pkey), gender, birth_date
patient_diagnosis contains the diagnosis data of the registered patients. It has fields like: record_id (pkey), pid (fkey to patient_data(pid)), diagnosis_date and other related fields.
Now, I want to join these two tables on pid and have all these fields in a single type of object.
Here is the mapping file:
<hibernate-mapping>
<class catalog="emr" name="in.Models.Emr" table="patient_diagnosis">
<id name="recordid" type="long">
<column name="record_id"/>
</id>
<property name="diagnosisDate" type="timestamp">
<column length="19" name="diagnosis_date" not-null="true"/>
</property>
<property name="snomedTermPrimary" type="long">
<column name="snomed_term_primary" not-null="true" />
</property>
<property name="snomedTermSecondary" type="string">
<column name="snomed_term_secondary" />
</property>
<property name="episodeNo" type="long">
<column name="episode_no" not-null="true" />
</property>
<property name="pid" type="long">
<column name="pid" not-null="true" />
</property>
<join table="patient_data">
<key column="pid"/>
<property name="gender" type="string">
<column name="gender" not-null="true"/>
</property>
<property name="birthDate" type="timestamp">
<column length="19" name="birth_date" not-null="true"/>
</property>
</join>
</class>
</hibernate-mapping>
But, the join applies on patient_diagnosis.record_id = patient_data.pid instead of patient_diagnosis.pid = patient_data.pid i.e. HQL applies on primary key of first table with mentioned column from second table.
Please provide the solution so that join can be applied on mentioned column from first with mentioned column from second table. Or is there another way out?
Please note that in case I didn't create classes for patient_data or patient_diagnosis. But, just Emr class having combination of fields of these tables is created.
Try giving foreign key
<id name="pid" type="java.lang.Long">
<column name="pid" />
<generator class="foreign">
<param name="property">patient_data</param>
</generator>
</id>
I am not sure but maybe this should work.
And
<one-to-one name="patient_data" class="in.Models.Emr"
cascade="save-update"></one-to-one>
Similarly in Join class
<one-to-one name="patient_diagnosis" class="in.Models.Emr"
cascade="save-update"></one-to-one>
I hope this helps you.

Table missing error while maaping MySQL view to hibernate

I am trying to map a MySql view to hibernate. But when I am getting and Table missing error while starting the application.
view is
CREATE
ALGORITHM = UNDEFINED
DEFINER = `mydbadmin`#`%`
SQL SECURITY DEFINER
VIEW `Reservation_Transaction_view` AS
select
convert( concat(`apst`.`Tid`,
_utf8'-',
`apst`.`RoomIndex`,
_utf8'-',
`apst`.`Rid`) using utf8) AS `id`,
`apst`.`Tid` AS `transactionId`,
`apst`.`RoomIndex` AS `room no`,
`apst`.`Pid` AS `paymentId`,
`apst`.`Rid` AS `reservationId`
from
`agent_payment_sub_transaction` `apst`
where
(`apst`.`Rid` <> 0)
group by `apst`.`Tid` , `apst`.`RoomIndex`
The mapping
<?xml version="1.0"?>
<hibernate-mapping>
<class name="com.abc.def.entity.ReservationTransactionView"
table="Reservation_Transaction_view" catalog="abcd">
<id name="id" type="string" />
<property name="transactionId" type="java.lang.Integer">
<column name="transactionId" />
</property>
<property name="roomNo" type="java.lang.Integer">
<column name="`room no`" />
</property>
<property name="paymentId" type="java.lang.Integer">
<column name="paymentId" />
</property>
<property name="reservationId" type="java.lang.Integer">
<column name="reservationId" />
</property>
The error is as followed.
org.hibernate.HibernateException: Missing table: Reservation_Transaction_view
I am using MySQL and Hibernate3.0 Please Help me for this query.
Thanks in advance.

Making join with Criteria

I'm terribly new to Hibernate. I've googled for two hours but I still can't figure out, how to make JOIN without using HQL, only by criteria. I have tables Clients(cID, name) and Visits(vID, vcID, date). The relation is one to many (one client can visit multiple times). I would also like to do it without setFetchMode. Just Criteria. Do I have to change the mappping xml?
UPDATE:
this is part of my mapping xml:
<class name="Client" table="Clients">
<id name="cID" column="cID"><generator class="native"/></id>
<property name="name" length="10" not-null="true"/>
</class>
<class name="Visit" table="Visits">
<id name="vID" column="vID"><generator class="native"/></id>
<property name="vcID" length="10" not-null="true"/>
<property name="date" length="25" not-null="true"/>
</class>
Having a class Client with a list-attribute "visits" that's mapping to your Visit-Entity:
Criteria criteria = session.createCriteria(Client.class);
criteria.addCriteria("visits");
This would create an inner join between your client-table and your visits-table.
Update:
Here you'll find some good examples: http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/querycriteria.html#querycriteria-associations
Mapping Example
I hardly ever use hibernate mapping xml, however it should read similiar to:
<class name="Client" table="Clients">
<id name="cID" column="cID"><generator class="native"/></id>
<property name="name" length="10" not-null="true"/>
<bag name="visits">
<key column="vcId"/>
<one-to-many class="Visit"/>
</bag>
</class>
Tell Hibernate that there is a property "visits" which represents a one-to-many relationship.
You need to update you mapping:
<class name="Client" table="Clients">
<id name="cID" column="cID"><generator class="native"/></id>
<property name="name" length="10" not-null="true"/>
<!-- Declare Set<Visit> visits in the Client class-->
<set name="visits" lazy="false" cascade="all">
<key column="vcID"/>
<one-to-many class="your.package.Visit"/>
</set>
</class>
<class name="Visit" table="Visits">
<id name="vID" column="vID"><generator class="native"/></id>
<!-- and add "Client client" property to your Visit class -->
<many-to-one name="client" column="vcID" lazy="false"/>
<property name="date" length="25" not-null="true"/>
</class>
Then:
Criteria criteria = session.createCriteria(Visit.class).addCriteria("client")
.add(Restriction.eq(...));
or
Criteria criteria = session.createCriteria(Client.class).addCriteria("visits")
.add(Restriction.eq(...));
And Hibernate will join them automatically.

Insert into join table in many-to-many relationship

Problem #1:
I have three tables; User, UserRole, and UserRoleRelationships (join table). The UserRole table contain all the user roles which I want to associate with the user. When I insert a new user I want to add a new user and add a new association in the join table. Now, when I'm running the query for inserting a new user:
IWUser iwUser = new IWUser();
iwUser.setUsername("username");
iwUser.setFullName("fullName");
iwUser.setEmail("email");
iwUser.setPassword("password");
iwUser.setPrivatephone("55555");
iwUser.setWorkphone("777");
Set<IWUserRole> roleList = new HashSet<IWUserRole>();
IWUserRole iwUserRole = new IWUserRole();
iwUserRole.setRole("ROLE_USER");
roleList.add(iwUserRole);
iwUser.setUserRole(roleList);
iwUserManagementService.saveOrUpdate(iwUser);
hibernate is running the following queries:
Hibernate: insert into dbo.Users (Username, Password, Email, Workphone, Privatephone, FullName) values (?, ?, ?, ?, ?, ?)
Hibernate: insert into dbo.UserRoles (Role) values (?)
Hibernate: insert into UserRoleRelationships (UserId, RoleId) values (?, ?)
My hibernate mapping looks like:
IWUser.hbm.xml:
<hibernate-mapping>
<class name="domain.IWUser" schema="dbo" table="Users">
<id name="userId" type="int">
<column name="UserId"/>
<generator class="native"/>
</id>
<property name="username" type="string">
<column name="Username" not-null="true"/>
</property>
<property name="password" type="string">
<column name="Password" not-null="true"/>
</property>
<property name="email" type="string">
<column name="Email" not-null="false"/>
</property>
<property name="workphone" type="string">
<column name="Workphone" not-null="false"/>
</property>
<property name="privatephone" type="string">
<column name="Privatephone" not-null="false"/>
</property>
<property name="fullName" type="string">
<column name="FullName" not-null="false"/>
</property>
<set cascade="all" inverse="false" name="userRole" table="UserRoleRelationships" lazy="true" >
<key>
<column name="UserId"/>
</key>
<many-to-many class="domain.IWUserRole" column="RoleId"/>
</set>
</class>
</hibernate-mapping>
IWUserRole.hbm.xml:
<hibernate-mapping>
<class name="domain.IWUserRole" schema="dbo" table="UserRoles">
<id name="roleId" type="int">
<column name="RoleId"/>
<generator class="native"/>
</id>
<property name="role" type="string">
<column name="Role" not-null="true"/>
</property>
<set cascade="all" inverse="false" name="user" table="UserRoleRelationships" lazy="true">
<key>
<column name="RoleId"/>
</key>
<many-to-many class="domain.IWUser" column="UserId"/>
</set>
</class>
</hibernate-mapping>
How can I get hibernate to save the new user with an existing user role in the join table?
Problem #2:
When I update the user, hibernate delete the relations in the join table. How can I avoid this?
How can I get hibernate to save the new user with an existing user role in the join table?
Retrieve the user role entity and put that into the list instead of always creating a new one.
I mean this part:
IWUserRole iwUserRole = new IWUserRole();
iwUserRole.setRole("ROLE_USER");
Instead, you'd issue a query like select r from IWUserRole where r.role = 'ROLE_USER'

Categories

Resources