Hibernate Error indexing: null when checking if row exists - java

I am trying to check if a row exists in my database.
Word word = (Word) session.createQuery("select 1 from Word w where w.content = :key").setParameter("key",words[i]).uniqueResult();
I'm also trying:
Word word = session.get(Word.class,contentId);
Besides that I tried session.load,and some others. Everytime Hibernate returns error:
Error indexing: null
or
Error indexing: no row with the given identifier exists.
It is true, row does not existing but why doesn't it just returns null like it should for session.get:
http://docs.jboss.org/hibernate/orm/3.5/javadocs/org/hibernate/Session.html#get(java.lang.Class,%20java.io.Serializable).
In case of not finding a row I wanted to create one and add to a database but I'm not able to check if it exists.
EDIT:
Word.java
public class Word {
private String content;
private Set<Sentence> sentences;
empty constructor, setters and getters
}
Word.hbm.xml
<class name="Word">
<id name="content" column="wordId" type="string">
</id>
<set name="sentences" inverse="true">
<key><column name="wordId"/></key>
<many-to-many class="Sentence" column="sentenceId"/>
</set>
</class>
Sentence.java
public class Sentence {
private long id;
private ProcessedUrl processedUrl;
private List<Word> words;
empty constructor, setters and getters
}
Sentence.hbm.xml
<class name="Sentence">
<id name="id" column="sentenceId">
<generator class="native"/>
</id>
<many-to-one name="processedUrl" column="processedUrlId" not-null="true"/>
<list name="words">
<key>
<column name="sentenceId" not-null="true"/>
</key>
<list-index column="idx" />
<many-to-many class="Word">
<column name="wordId" not-null="true"/>
</many-to-many>
</list>
</class>

Related

What is a proper way to delete a list of objects in Hibernate?

I have an object User, which has a List of UserDictionary. Each UserDictionary has a List of UserWords with cascade delete.
User.java
public class User implements Serializable
{
private Long id;
private String login;
private String password;
private String email;
private Boolean isVerified;
private List<UserDictionary> dictionaries = new ArrayList<>();
private UserTrainingSettings settings;
//getters and setters there
}
And mapping User.hbm.xml
<hibernate-mapping>
<class name="User" dynamic-insert="true" dynamic-update="true" table="USER" entity-name="user">
<id name="id" type="java.lang.Long" column="user_id">
<generator class="native"/>
</id>
<property name="login" type="java.lang.String" length="40" not-null="true" unique="true"/>
<property name="password" type="java.lang.String" length="32" not-null="true"/>
<property name="email" type="java.lang.String" length="100" not-null="true"/>
<property name="isVerified" type="java.lang.Boolean" column="verified" not-null="true"/>
<list name="dictionaries" fetch="join">
<key column="user_id" not-null="true" on-delete="cascade"/>
<one-to-many class="com.github.wordsmemoriser.Model.UserDictionary"/>
</list>
<one-to-one name="settings" class="com.github.wordsmemoriser.Model.UserTrainingSettings"
cascade="javax.persistence.CascadeType.REMOVE"/>
</class>
</hibernate-mapping>
UserDictionary.java
public class UserDictionary
{
private Long id;
private User user;
private String name;
private List<UserWords> words = new ArrayList<>();
//getters and setters there
}
And mapping UserDictionary.hbm.xml
<hibernate-mapping>
<class name="UserDictionary" dynamic-insert="true" dynamic-update="true" table="DICTIONARY">
<id name="id" type="java.lang.Long" column="dict_id">
<generator class="native"/>
</id>
<many-to-one name="user" class="com.github.wordsmemoriser.Model.User" fetch="join">
<column name="user_id" not-null="true"/>
</many-to-one>
<property name="name" type="java.lang.String" length="100"/>
<list name="words">
<key column="dict_id" not-null="true" on-delete="cascade"/>
<one-to-many class="com.github.wordsmemoriser.Model.UserWords"/>
</list>
</class>
</hibernate-mapping>
What is a proper way to delete all UserDictionaries from User? Should I iterate this list, delete every UserDictionary from database, then clear this list and update User like this
session.beginTransaction();
for(UserDictionary dict : user.getDictionaries())
{
session.delete(dict);
}
user.getDictionaries().clear();
session.update(user);
session.getTransaction().commit();
or should I just clear User's list and then update it like this
user.getDictionaries().clear();
session.beginTransaction();
session.update(user);
session.getTransaction().commit();

Hibernate Criteria API where clause in many to many relation

I have relation many to many with extra fileds in linking table(mapping in xml files). Using criteria api how to add restrictions to name of product?
public class Recipe implements Serializable{
private int id_re;
private String name;
private Set<ProductRecipe> listOfRecipe_Product = new HashSet<>(0);
}
public class ProductRecipe implements Serializable{
private ProductRecipeMapping id;
private float quantity;
}
public class ProductRecipeMapping implements Serializable{
private Product product;
private Recipe recipe;
}
public class Product implements Serializable{
private int id_p;
private String name;
}
Mapping:
<class entity-name="recipe" name="Recipe" table="recipe">
<id name="id_re" type="java.lang.Integer">
<column name="id_re" />
<generator class="identity" />
</id>
<set name="listOfRecipe_Product" table="recipe_product" lazy="false" fetch="select" cascade="all">
<key>
<column name="id_re" not-null="true" />
</key>
<one-to-many entity-name="productRecipe" />
</set>
</class>
<class entity-name="productRecipe" name="ProductRecipe" table="recipe_product">
<composite-id name="id" class="ProductRecipeMapping" >
<key-many-to-one name="recipe" entity-name="recipe" column="id_re" />
<key-many-to-one name="product" entity-name="product" column="id_p" />
</composite-id>
<property name="quantity" type="float" column="quantity" />
</class>
<class entity-name="product" name="Product" table="product">
<id name="id_p" type="java.lang.Integer" column="id_p">
<generator class="identity" />
</id>
<property name="name" column="name" type="java.lang.String" not-null="true" length="255"/>
</class>
E.G. I use criteria for get recipe with name test:
Criteria cr = session.createCriteria(Recipe.class);
cr.add(Restrictions.eq("name", "test"));
but I don't know to get all recipes with list name of products
something like cr.add(Restrictions.eq("product.name", "test")); (but not work)
I use 2 idea to resolve this problem but nothing work:
1) Restrictions.eq("listOfRecipe_Product.id.product.name", "test")
but i get error org.hibernate.QueryException: could not resolve property: listOfRecipe_Product.id.product.name of: recipe
2)
cr.createCriteria("listOfRecipe_Product")
.createCriteria("id")
.createCriteria("product")
.add(Restrictions.eq("name", "test"));
I get error org.hibernate.QueryException: Criteria objects cannot be created directly on components. Create a criteria on owning entity and use a dotted property to access component property: listOfRecipe_Product.id
You will need to create aliases in order to add constraints to mapped entities;
e.g.:
Criteria cr = session.createCriteria(Recipe.class)
.createAlias("listOfRecipe_Product", "listOfRecipe_Product")
.createAlias("listOfRecipe_Product.id", "id")
.createAlias("id.product", "product")
.add(Restrictions.eq("product.name", "test"));

Hibernate criteria specific query

I have such entity:
public class LogEntity implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private Date changeTime;
private Set<Integer> changes;
//getters and setters
}
And its mapping:
<hibernate-mapping>
<class name="com.myproject.dao.LogEntity" table="LOG">
<id name="id" column="ID" type="integer">
<generator class="native" />
</id>
<property name="changeTime" column="CHANGE_TIME" type="timestamp"/>
<set name="changes" table="LOG_CHANGES" lazy="false" cascade="all" order-by="CHANGE_ID">
<key column="ID"/>
<element column="CHANGE_ID" type="integer"/>
</set>
</class>
The problem is how to check that Set<Integer> changes contains given parameter using hibernate criteria. I can't createAlias() for this and also try to use sqlRestriction() but get something ugly.
I am pretty sure that there is some easy way but I just cant see it. Thanks for any help.

Hibernate many-to-many data retrieval

I have two objects User and Contact, with many to many relation, and I am using an intermediate table for this relation USER_CONTACT
Saving the data in this association is fine, but the retrieval is an issue.
I need to retrieve the data based on the User, but what I am getting is all the Contacts, for all the Users.
It will be good if you can let me know what wrong I am doing.
public class User {
private Integer userID;
private String userLoginEmail;
private String password;
private Set<Contact> contactSet = new HashSet<Contact>();
.
.
}
public class Contact implements Serializable {
private Integer contactID;
private String givenName;
private String familyName;
private Set<User> userSet = new HashSet<User>();
.
.
}
User.hbm.xml:
<class name="User" table="USERACCOUNT">
<id column="USER_ID" length="500" name="userID">
<generator class="increment" />
</id>
<property column="USER_LOGIN_EMAIL" generated="never" lazy="false" length="100" name="userLoginEmail" />
<property column="USER_FIRSTNAME" generated="never" lazy="false" length="100" name="userFirstName" />
<property column="USER_LASTNAME" generated="never" lazy="false" length="100" name="userLastName" />
<set name="contactSet" table="USER_CONTACT" inverse="false" lazy="false" fetch="select" cascade="all">
<key column="USER_ID"/>
<many-to-many column="CONTACT_ID" class="com.smallworks.model.Contact"/>
</set>
</class>
Contact.hbm.xml
<class name="Contact" table="CONTACT">
<id column="CONTACT_ID" length="500" name="contactID">
<generator class="increment"/>
</id>
<property column="GIVEN_NAME" generated="never" lazy="false" length="100" name="givenName"/>
<property column="FAMILY_NAME" generated="never" lazy="false" length="100" name="familyName"/>
<!-- many to many mapping with the User via User_Contact table -->
<set inverse="true" lazy="false" name="userSet" sort="unsorted" table="USER_CONTACT">
<key column="USER_ID"/>
<many-to-many class="com.smallworks.model.Contact" column="CONTACT_ID" unique="false"/>
</set>
</class>
and this is how I am trying to retrieve the data, which I think is not correct.
List contactList = session.createQuery("from Contact").list();
It will be good if I can know how to go about getting the Contacts based on the User.
// First, retrieve the user you want.
User user = (User) session.get(User.class, user_id_you_want);
// Second, get the contacts of that given user and add them to a list (optional)
List contacts = new ArrayList();
contacts.addAll(user.getContactSet());
return contacts;

Mapping same class relation

Hi
I’m trying to map some classes in hibernate there and have general problem how such mapping can be done.
There is User class and Facebook user class which has the following structure
User Class :
public class User{
public User(){}
Long Id;
String FirstName;
String LastName;
....
FbUser fbuser;
//// all requred
getters and setters...
}
Facebook class FbUser can have list of Friends which are objects of the same class FbUser.
public class FbUser{
public FbUser(){}
Long fbId;
String FirstName;
String LastName;
List<FbUser> friends;
//// all requred
getters and setters...
}
Till now I made many to one relation between User And FbUser.
<hibernate-mapping>
<class
name="User"
table="User"
>
<id
name="Id"
column="ID"
type="java.lang.Long"
unsaved-value="null"
>
<generator class="increment"/>
</id>
<property
name="FirstName"
update="true"
insert="true"
not-null="false"
unique="false"
type="java.lang.String"
>
<column name="FirstName" />
</property>
<property
name="LastName"
update="true"
insert="true"
not-null="false"
unique="false"
type="java.lang.String"
>
<column name="LastName" />
</property>
<many-to-one
name="fbUser"
class="FbUser"
cascade="all"
column="fbId"
unique="true"
/>
</class>
</hibernate-mapping>
And now the FbUser Mapping:
<hibernate-mapping>
<class
name="FbUser"
table="FbUser"
>
<id
name="fbId"
column="fbId"
type="java.lang.Long"
unsaved-value="null"
>
<generator class="increment"/>
</id>
<property
name="FirstName"
update="true"
insert="true"
not-null="false"
unique="false"
type="java.lang.String"
>
<column name="FirstName" />
</property>
<property
name="LastName"
type="java.lang.String"
update="true"
insert="true"
column="LastName"
not-null="true"
unique="false"
/>
</class>
</hibernate-mapping>
Chow can I map FbUser List inside the FbUser Map file? I got lost :(
You can create an additional class named, for instance, MyFriends
public class FbUser {
List<MyFriends> friends = new ArrayList<MyFriends>();
}
Just relevant part
If you have a index-column
<hibernate-mapping>
<class name="FbUser">
<list name="myFriends">
<key column="ME_ID" insert="false" update="false"/>
<list-index column="WHICH COLUMN SHOULD BE USED AS INDEX"/>
<one-to-many class="MyFriends"/>
</list>
</class>
</hibernate-mapping>
If you do not have a index-column
re-write your list as
public class FbUser {
Collection<MyFriends> friends = new ArrayList<MyFriends>();
}
And
<hibernate-mapping>
<class name="FbUser">
<bag name="columns">
<key column="ME_ID" insert="false" update="false"/>
<one-to-many class="MyFriends"/>
</bag>
</class>
</hibernate-mapping>
And your MyFriends mapping. Notice you need a composite primary key (implemented as a static inner class)
<class name="MyFriends">
<composite-id name="myFriendsId" class="MyFriends$MyFriendsId">
<key-property name="meId"/>
<key-property name="myFriendId"/>
</composite-id>
<many-to-one name="me" class="FbUser" insert="false" update="false"/>
<many-to-one name="myFriend" class="FbUser" insert="false" update="false"/>
</class>
Your MyFriends is shown as follows
public class MyFriends {
private MyFriendsId myFrinedId;
private FbUser me;
private FbUser myFriend;
public static class MyFriendsId implements Serializable {
private Integer meId;
private Integer myFriendId;
// getter's and setter's
public MyFriendsId() {}
public MyFriendsId(Integer meId, Integer myFriendId) {
this.meId = meId;
this.myFriendId = myFriendId;
}
// getter's and setter's
public boolean equals(Object o) {
if(!(o instanceof MyFriendsId))
return false;
MyFriendsId other = (MyFriendsId) o;
return new EqualsBuilder()
.append(getMeId(), other.getMeId())
.append(getMyFriendId(), other.getMyFriendId())
.isEquals();
}
public int hashcode() {
return new HashCodeBuilder()
.append(getMeId())
.append(getMyFriendId())
.hashCode();
}
}
}
Well, first: User has a one-to-one relation with FbUser, correct?
second: Map FbUser to FbUser as a many to many relation using a list or a set. I have an Set example here:
<set
name="friends"
table="FbUser" <!-You may use other table here if you want->
access="field">
<key
column="fbId"/>
<many-to-many
class="bla.bla.bla.FbUser"
column="friend_id" />
</set>

Categories