Im trying to insert and select data in mysql database trough Hibernate and Insert is working fine for me but select somehow dont map the right table name and returns me no result.
Get and insert code:
SessionFactory sessFact = HibernateUtil.getSessionFactory();
Session session = sessFact.getCurrentSession();
session.beginTransaction();
session.save(obj);
session.getTransaction().commit();
try {
Session mysession = HibernateUtil.getSessionFactory().getCurrentSession();
mysession.beginTransaction();
weatherDataObject resultObjectHib = (weatherDataObject) mysession.get(weatherDataObject.class, 26);
mysession.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
}
sessFact.close();
<?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">
<hibernate-mapping package="some.pack">
<class name="weatherCoordinates" table="coordinates">
<id name="dataBaseId" column="coordinates_id">
<generator class="native" />
</id>
<property name="lat" type="string" column="coordinates_lat" />
<property name="lon" type="string" column="coordinates_lon" />
</class>
</hibernate-mapping>
<?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">
<hibernate-mapping package="some.pack">
<class name="weatherDataObject" table="data_object">
<id name="id" column="data_object_id">
<generator class="native" />
</id>
<property name="name" type="string" column="data_object_name" />
<many-to-one name="coord" class="task.main.DataObjects.weatherCoordinates"
column="coordinates_id" unique="true" not-null="true" cascade="all" />
</class>
</hibernate-mapping>
When I see sql execution strings it is :
Hibernate: insert into coordinates (coordinates_lat, coordinates_lon) values (?, ?)
Hibernate: insert into data_object (data_object_name, coordinates_id) values (?, ?)
Hibernate: select weatherdat0_.data_object_id as data_obj1_1_0_, weatherdat0_.data_object_name as data_obj2_1_0_, weatherdat0_.coordinates_id as coordina3_1_0_ from data_object weatherdat0_ where weatherdat0_.data_object_id=?
The problem is weatherdat0 that somehow is wrong my table is called the way I mapped it in the file data_object don't know how and why it is changed anybody can help ?
The query is generated on correct table, as the select query is run on table from data_object
The weatherdat0_is just an alias for the table as mentioned in the from statement:
from data_object weatherdat0_
So it is picking correct table name only.
Now if the query is not returning any results means there are no records matching that id so I suggest you to run the query directly on database and see if it returns any records.
Related
I need to execute select ST_AsText(column_name) from table using hibernate createSQlQuery().
When i executed that query, it fires an exception.
But when i execute the same query using simple JDBC or in my PGAdmin browser, the query works.
Below is my query:
select st_astext(linkPoints) from linkRoute
Exception:
SEVERE: ERROR: relation "linkroute" does not exist
Mapping File
<?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="com.lnt.utility.pojo.linkRoute" table="link_route">
<id name="Id" column="id">
<generator class="assigned" />
</id>
<property name="linkName" column="link_name"/>
<property name="distance" column="distance"/>
<property name="idNo" column="idno"/>
<property name="speed" column="speed"/>
<property name="linkPoints" column="link_points"/>
</class>
</hibernate-mapping>
Pls help
Hibernate provide a createSQLQuery method to let you call your native SQL statement directly.
I hope you should be able to work with your query using nativequery else you should go for Hibernate Spatial.
Please find the link for more information on hibernate native query tutorial. Hope this helps.
I found the following links:
Hibernate one to one mapping problem
Hibernate one-to-one mapping with a reference column (XML mapping)
hibernate one-to-one (on foreign key) vs one-to-one (on primary key)
But nothing seems to work.
I have 2 entities:
class User {
Integer userId;
Profile userProfile;
}
class Profile {
Integer profileId;
User user;
}
With XML mapping:
<?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">
<hibernate-mapping>
<class name="model.User" table="User" catalog="Proj1" dynamic-update="true">
<id name="userId" type="java.lang.Integer">
<column name="userId" />
<generator class="identity" />
</id>
<one-to-one name="userProfile" class="model.Profile">
</one-to-one>
</class>
</hibernate-mapping>
<?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 Jun 12, 2013 7:51:22 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="model.Profile" table="Profile" catalog="Proj1" dynamic-update="true">
<id name="profileId" type="java.lang.Integer">
<column name="profileId" />
<generator class="identity" />
</id>
<many-to-one name="user" class="model.Users" unique="true">
<column name="userId" />
</many-to-one>
</class>
</hibernate-mapping>
The thing here is, the User must have exactly one Profile but the Profile doesn't necessarily to have one User so a Profile may have null User.
Now the problem is every time I fetch a User with its associated Profile, the Profile retrieved is the Profile with the profileId the same as userId, that is if the User has userId 4 the Profile retrieved is the profile with profileId 4 as well even though it is supposed to retrieve Profile with userId 4 not profileId 4.
Update: add Dao code
public User findById( int id ) {
log.debug("getting User instance with id: " + id);
try {
Criteria userCriteria = this.sessionFactory.getCurrentSession().createCriteria(User.class);
userCriteria.add(Restrictions.idEq(id));
userCriteria.setFetchMode("userProfile", FetchMode.JOIN);
userCriteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
Users instance = (Users) userCriteria.uniqueResult();
if(instance == null)
log.debug("get successful, no instance found");
else
log.debug("get successful, instance found");
return instance;
}
catch(RuntimeException re) {
log.error("get failed", re);
throw re;
}
}
Finally I found the solution. Originally I had to set the userProfile manually every time I need to fetch the associated userProfile of a User just for a temporary workaround. But I just found this link: http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/associations.html#assoc-bidirectional-121
So basically I just have to add unique="true" not-null="false" to the many-to-one of the user in Profile xml and add property-ref="user" to the one-to-one userProfile in User. I think the key here is the property-ref="user"
I have schema below:
Customer
id -Primary key
customer_name
phone
.............
Service
id -Primary key
customer_id -- foreign key to Customer.id
.................
Customer.hbm.xml
<?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="thesis.database.Customer" table="customer">
<meta attribute="class-description">
</meta>
<id name="customerId" type="int" column="customer_id">
<generator class="native" />
</id>
<property name="phone" column="phone" type="string" />
<bag name="services" table="use_service" inverse="false" fetch="join" lazy="false"
cascade="all">
<key column="customer_id" />
<one-to-many class="thesis.database.Service" />
</bag>
</class>
Service.hbm.xml
<?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="thesis.database.Service" table="service">
<meta attribute="class-description">
This class contains the Service detail.
</meta>
<id name="id" type="int" column="id">
<generator class="native" />
</id>
<many-to-one name="customer" class="thesis.database.Customer"
fetch="select">
<column name="customer_id" not-null="true" />
</many-to-one>
....................
</class>
My function
public static Customer getCustomerByPhoneNumber(String phoneNumber) {
Session session = getSession();
Criteria criteria = session.createCriteria(Customer.class);
Criterion phone = Restrictions.eq("phone", phoneNumber);
criteria.add(phone);
Customer customer = (Customer) criteria.uniqueResult();
session.close();
return customer;
}
And after that, i call
Customer customer = getCustomerByPhoneNumber("123456789"); // customer with this phone is availuable in database
I get this customer normally, but i cell getServices() function to get list service, it always get the same list, although i try to add more records to service table.
For example:
Customer table
id customer_name phone ................
1 Mr A 123456789................
and service table
id customer_id ........................
1 1 ........................
2 1 ........................
3 1 ........................
First query. i got list size = 3;
after insert one more record like that 4 1 ............ to service table
Second query. i also got list size = 3;
Can everybody tell me why and suggest any solution? thank in advance!
My solution is using Transaction to commit after adding new record.
Maybe you are forgetting to execute the criteria. Here http://docs.jboss.org/hibernate/orm/3.6/javadocs/org/hibernate/Criteria.html they are always calling the list method.
What do I have to change to avoid Hibernate giving me lazy javassist instance proxies rather than the true entity?
UPDATE: I am using Spring 3.x and Hibernate 4.x
The API I am using to load the entity is org.hibernate.internal.SessionImpl#load(Person.class, Id) and the mapping simply:
<?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">
<hibernate-mapping package="org.perfectjpattern.example.model">
<class name="Person" table="PERSON_" >
<id name="id">
<generator class="native"></generator>
</id>
<property name="name" update="false" />
<property name="age" update="true" />
</class>
<query name="Person.findByName">
<![CDATA[select p from Person p where p.name = ? ]]>
</query>
<query name="Person.findByAge">
<![CDATA[select p from Person p where p.age = :Age ]]>
</query>
</hibernate-mapping>
Use get() rather than load().
You can use Hibernate.initialize(obj) after session.load(id).
This method can instantly initialize your obj.
Actually solved it by simply changing the mapping to (see the default-lazy="false"):
<?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">
<hibernate-mapping package="org.perfectjpattern.example.model" default-lazy="false">
I am trying to use Hibernate to access persisted data for our rights management, but I am very new to it and struggling to get the data I need.
I have Users table, with an ID and name, a Groups table with an ID and name, and a User/Groups mapping which just consists of the group ids and user ids that are linked.
What I want to do is get all the names of the members of a given group, so the standard SQL query I want to execute is this:
SELECT
u.NAME
FROM
USERS u
JOIN
GROUP_USERS gu
ON
u.ID = gu.USER_ID
JOIN
GROUPS g
ON
gu.GROUP_ID = g.ID
WHERE
g.NAME = 'test'
But despite hours of looking and playing I cannot seem to get anywhere.
I want to use Criteria as they seem clearer, so my code is as follows:
#Override
public final List<String> getGroupMembers(final String groupName) {
#SuppressWarnings("unchecked")
List<User> groupUsers = getHibernateTemplate().execute(new HibernateCallback<List<User>>() {
#Override
public List<User> doInHibernate(Session session) throws HibernateException, SQLException {
Criteria criteria = session.createCriteria(User.class)
.setFetchMode("GroupUsers", FetchMode.JOIN)
.setFetchMode("Group", FetchMode.JOIN)
.add(Restrictions.eq("name", groupName));
return criteria.list();
}
});
List<String> groupUsernames = new ArrayList<String>();
for (User groupUser : groupUsers) {
groupUsernames.add(groupUser.getName());
}
return groupUsernames;
}
But when I test it the result set is empty, and according to the logs the executed query is this:
select this_.ID as M1_4_0_, this_.NAME as M2_4_0_ from USERS this_ where this_.NAME=?
I let Hibernate create the tables using hibernate.hbm2ddl.auto, but then removed it so that the tables are definitely as hibernate expects, but the data is not being cleaned.
Any help with the Criteria would be greatly appreciated, so thanks in advance!
Edit: I am using xml mapping files:
<?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 package="com.company">
<class name="com.company.Group" table="GROUPS">
<id name="id" column="ID" type="int">
<generator class="identity"/>
</id>
<property name="name" column="NAME" type="java.lang.String" unique="true" not-null="true"/>
</class>
</hibernate-mapping>
and
<?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 package="com.company">
<class name="com.company.GroupUsers" table="GROUP_USERS">
<composite-id>
<key-many-to-one name="groupId" class = "Group" column="GROUP_ID" />
<key-many-to-one name="userId" class = "User" column="USER_ID" />
</composite-id>
</class>
</hibernate-mapping>
and
<?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 package="com.company">
<class name="com.company.User" table="USERS">
<id name="id" column="ID" type="int">
<generator class="identity"/>
</id>
<property name="name" column="NAME" type="java.lang.String" unique="true" not-null="true"/>
</class>
</hibernate-mapping>
You don't need to map the user-group table, just define your relation between User and Group as a many-to-many relation, take a look at this and this about how to map many-to-many relations.
In your case, it will look like:
<hibernate-mapping package="com.company">
<class name="com.company.User" table="USERS">
<id name="id" column="ID" type="int">
<generator class="identity"/>
</id>
<property name="name" column="NAME" type="java.lang.String" unique="true" not-null="true"/>
<many-to-many name="userGroups"
target-entity="com.company.Group">
<join-table name="YOUR_USER_GROUP_TABLE">
<join-column name="USER_ID" />
<inverse-join-column name="GROUP_ID" />
</join-table>
</many-to-many>
</class>
And to filter your users using the name field from the Group entity for example:
Criteria criteria = session.createCriteria(User.class);
criteria.createAlias("userGroups", "usrGrp",CriteriaSpecification.LEFT_JOIN);
criteria.add( Restrictions.eqProperty("usrGrp.name", "test") )
The way you map your object to tables does not benefit from the usage of Hibernate as ORM. Consider a more object-oriented model, eg:
class Group {
private Set<User> users;
// ...
}
class User {
private Set<Group> groups;
//..
}
So, you've got a classical many-to-many association. Here you can find an example of such mapping with Hibernate.