org.hibernate.QueryParameterException: could not locate named parameter - java

My project setting are Spring MVC, Hibernate 3.2.x, on MySQL DB
Getting the following error:
org.hibernate.QueryParameterException: could not locate named parameter email
Approach #1:
#Override
public Boolean isExist(String email) {
boolean flag = false;
String hql = "from com.cmgr.beans.UserAccount u where u.email = :email";
List<UserAccount> result = currentSession().createQuery(hql)
.setParameter("email", email)
.list();
UserAccount userAccount = (UserAccount)result.get(0);
if (userAccount!=null && userAccount.getEmail().equalsIgnoreCase(email)) {
flag = true;
}
return flag;
}
Approach #2:
#Override
public Boolean isExist(String email) {
boolean flag = false;
String hql = "from com.cmgr.beans.UserAccount u where u.email = :email";
List<UserAccount> result = currentSession().createQuery(hql).setString("email", email).list();
UserAccount userAccount = (UserAccount) result.get(0);
if (userAccount != null && userAccount.getEmail().equalsIgnoreCase(email)) {
flag = true;
}
return flag;
}
Error:
java.lang.IllegalArgumentException: Parameter email does not exist as a named parameter in [from com.cmgr.beans.UserAccount u where u.email = :email]
UserAccount class:
package com.cmgr.beans;
import java.io.Serializable;
import java.util.List;
import java.util.Set;
import javax.persistence.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
#Entity
#Table(name = "user_account")
public class UserAccount implements Serializable {
#Autowired
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY, generator = "user_account_seq")
#SequenceGenerator(name = "user_account_seq", sequenceName = "user_account_seq")
#Column(name = "user_id")
private Long UserId = null;
//
#Autowired
#Column(name = "user_name")
private String UserName;
//
#Autowired
#Column(name = "user_type")
private String UserType = null;
//
#Autowired
#Column(name = "first_name")
private String FirstName;
//
#Autowired
#Column(name = "last_name")
private String LastName;
//
#Autowired
#Column(name = "email")
private String Email;
//
#Autowired
#Column(name = "phone_contact_1")
private String PhoneContact1 = null;
//
#Autowired
#Column(name = "phone_contact_2")
private String PhoneContact2 = null;
//primary_address_is_usa
#Autowired
#Column(name = "primary_address_is_usa")
private Boolean primaryAddressIsUsa = null;
//
#Autowired
#Column(name = "address_1")
private String Address1 = null;
//
#Autowired
#Column(name = "city1")
private String city1 = null;
//
#Autowired
#Column(name = "state1")
private String state1 = null;
//
#Autowired
#Column(name = "country1")
private String country1 = null;
//
#Autowired
#Column(name = "zipcode")
private Integer zipcode = 0;
//
#Autowired
#Column(name = "Industry")
private String Industry = null;
//is the user account Active either due to user deactivation,admin deactivation, or nonpayment
#Autowired
#Column(name = "active")
private boolean Active = false;
//1 to 1 relation with registerationCode in Registeration class
#Autowired
#Qualifier("UserRegisteration")
#OneToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "Registeration_Code_fk", referencedColumnName = "registeration_code", nullable = false)
private UserRegisteration UserRegisteration;
//1 to many relation with EmailId in Email class
#OneToMany(cascade = {CascadeType.ALL})
#JoinColumn(name = "emailed_id")
private List<Emailed> emailed = null;
//1 to many relation with signatureId in signature class
#OneToMany(cascade = {CascadeType.ALL})
#JoinColumn(name = "signature_id")
private List<Signature> signatures;
//1 to many relation with UserAccountDocId in UserAccountDoc class
#OneToMany(cascade = {CascadeType.ALL})
#JoinColumn(name = "user_doc_id")
private Set<UserAccountDocumentRelationship> UserAccountDocumentRelationship;
#Autowired(required = false)
public UserAccount() {
}
#Autowired(required = true)
public UserAccount(String UserName, String FirstName, String LastName, String Email, String Industry) {
this.FirstName = FirstName;
this.LastName = LastName;
this.Email = Email;
this.Industry = Industry;
this.UserName = UserName;
}
#Autowired(required = false)
public UserAccount(String UserName, Long UserId, String FirstName, String LastName, String Email, String Industry) {
this.UserId = UserId;
this.FirstName = FirstName;
this.LastName = LastName;
this.Email = Email;
this.Industry = Industry;
this.UserName = UserName;
}
public String getIndustry() {
return Industry;
}
public void setIndustry(String Industry) {
this.Industry = Industry;
}
public String getAddress1() {
return Address1;
}
public void setAddress1(String Address1) {
this.Address1 = Address1;
}
public String getPhoneContact1() {
return PhoneContact1;
}
public void setPhoneContact1(String PhoneContact1) {
this.PhoneContact1 = PhoneContact1;
}
public String getPhoneContact2() {
return PhoneContact2;
}
public void setPhoneContact2(String PhoneContact2) {
this.PhoneContact2 = PhoneContact2;
}
public boolean isActive() {
return Active;
}
public void setActive(boolean Active) {
this.Active = Active;
}
public String getEmail() {
return Email;
}
public void setEmail(String Email) {
this.Email = Email;
}
public String getFirstName() {
return FirstName;
}
public void setFirstName(String FirstName) {
this.FirstName = FirstName;
}
public String getLastName() {
return LastName;
}
public void setLastName(String LastName) {
this.LastName = LastName;
}
public com.cmgr.beans.UserRegisteration getUserRegisteration() {
return UserRegisteration;
}
public void setUserRegisteration(com.cmgr.beans.UserRegisteration UserRegisteration) {
this.UserRegisteration = UserRegisteration;
}
public Long getUserId() {
return UserId;
}
public void setUserId(Long UserId) {
this.UserId = UserId;
}
public String getUserType() {
return UserType;
}
public void setUserType(String UserType) {
this.UserType = UserType;
}
public List<Emailed> getEmailed() {
return emailed;
}
public void setEmailed(List<Emailed> emailed) {
this.emailed = emailed;
}
public List<Signature> getSignatures() {
return signatures;
}
public void setSignatures(List<Signature> signatures) {
this.signatures = signatures;
}
public String getCity1() {
return city1;
}
public void setCity1(String city1) {
this.city1 = city1;
}
public String getCountry1() {
return country1;
}
public void setCountry1(String country1) {
this.country1 = country1;
}
public Boolean getPrimaryAddressIsUsa() {
return primaryAddressIsUsa;
}
public void setPrimaryAddressIsUsa(Boolean primaryAddressIsUsa) {
this.primaryAddressIsUsa = primaryAddressIsUsa;
}
public String getState1() {
return state1;
}
public void setState1(String state1) {
this.state1 = state1;
}
public Integer getZipcode() {
return zipcode;
}
public void setZipcode(Integer zipcode) {
this.zipcode = zipcode;
}
public String getUserName() {
return UserName;
}
public void setUserName(String UserName) {
this.UserName = UserName;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final UserAccount other = (UserAccount) obj;
if ((this.UserId == null) ? (other.UserId != null) : !this.UserId.equals(other.UserId)) {
return false;
}
return true;
}
#Override
public int hashCode() {
int hash = 3;
hash = 73 * hash + (this.UserId != null ? this.UserId.hashCode() : 0);
return hash;
}
public Set<com.cmgr.beans.UserAccountDocumentRelationship> getUserAccountDocumentRelationship() {
return UserAccountDocumentRelationship;
}
public void setUserAccountDocumentRelationship(Set<com.cmgr.beans.UserAccountDocumentRelationship> UserAccountDocumentRelationship) {
this.UserAccountDocumentRelationship = UserAccountDocumentRelationship;
}
}

From what i remember, this is a case of Hibernate reporting the wrong error message. I guess, the actual error is "mapping not found for com.cmgr.beans.UserAccount". Try this query:
String hql = "from com.cmgr.beans.UserAccount";
This probably will show you the correct error message. And once you fix that, you can change it to accept the parameters.

Today i had a similar issue...
My entity was not in the scanned packages from Spring. So Hibernate somehow did something but the error message was quite confusing and did not really fit to the real issue.
To solve my problem i had to add the entities to the packagescan.

Change your query to
String hql = "from com.cmgr.beans.UserAccount u where u.Email = :email";
Since your UserAccount class has a property of Email

Hibernate somewhy throws different exception than it has to be.. Probably by correcting this you should get rid of the problem:
Rename fields in the class to follow JavaConventions (should start with a small letter)
Use simple class name instead of fully qualified

I see that in the UserAccount class, the property for the email address is defined as 'Email' and not 'email'.
Refer to the hibernate documentation
It is advisable to use java naming convention hence I would advice you to name your property to 'email' in UserAccount.

replace:
#Autowired
#Column(name = "email")
private String Email;
//
with:
#Autowired
private String email;
use java naming conventions of variable naming small letters & don't need to write
#Column(name = "email")
because variable name is same name as column name

Just Try this....
In place of
List<UserAccount> result = currentSession().createQuery(hql)
.setParameter("email", email)
.list();
use
List<UserAccount> result = currentSession().createQuery(hql)
.setString("email", email)
.list();
may be it will helps you....

Verify that in the SQL query the parameter starts with ':'
Example: WHERE NAME = :pMyParameter
At the same time, you must take into account that in the Java code the parameter must not be named with ':'
Example: parameters.put("pMyParameter", myParameter);
may be it will helps you...

Related

`RollbackException: Error while committing the transaction` when trying to save an object with Spring JPA and MySQL

I'm trying to save an object in my MySQL DB by using Spring JPA.
That's the error I get:
[nio-8088-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Resolved
[org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction]
That's where I'm trying to save my object:
#Override
public RegistrationV1Response registerUser(#Valid RegistrationV1Request registrationV1Request) {
User user = new User();
user.setFirstname(registrationV1Request.getFirstname());
user.setLastname(registrationV1Request.getLastname());
user.setUsername(registrationV1Request.getUsername());
user.setEmail(registrationV1Request.getEmail());
user.setPassword(new BCryptPasswordEncoder().encode(registrationV1Request.getPassword()));
user.setActive(true);
userRepository.save(user);
return new RegistrationV1Response().withUser(user);
}
The UserRepository:
#Repository
public interface UserRepository extends CrudRepository<User, Long> {
public User findFirstByUsername(String username);
}
The User class:
#javax.persistence.Entity
#Table(name = "users")
public class User extends Entity {
#Column(name = "firstname", nullable = false, length = 100)
#NotEmpty()
private String firstname;
#Column(name = "lastname", nullable = false, length = 100)
#NotEmpty()
private String lastname;
#Column(name = "password", nullable = false, length = 100)
#NotEmpty()
private String password;
#Column(name = "username", nullable = false, unique = true, length = 100)
#NotEmpty()
private String username;
#Column(name = "email", nullable = false, unique = true, length = 100)
#NotEmpty()
#Email()
private String email;
#Column(name = "active", nullable = false)
#NotEmpty()
private boolean active;
#Column(name = "description", nullable = true, length = 250)
private String description;
#OneToMany(targetEntity = Post.class, mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Post> posts;
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public boolean isActive() { return active; }
public void setActive(boolean active) { this.active = active; }
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public List<Post> getPosts() { return posts; }
public void setPosts(List<Post> posts) { this.posts = posts; }
}
The Post class:
#javax.persistence.Entity
#Table(name = "posts")
public class Post extends Entity {
#Lob
#Column(name = "text", nullable = false)
#NotEmpty()
private String text;
#ManyToOne(targetEntity = User.class)
private User user;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
Reading from the DB work's without any problems just save (insert / update) doesn't work.
I just read on a similar issue that I need to add the #Transational property to the method. I did this and it's still not working. Also the other possible solutions / statements of similar issues aren't working. They're mostly about missconfigured relations or something and that's not the problem in my case I think.

OneToMany relationship error: Field 'XX' doesn't have a default value

I'm trying to create One-To-Many relationship between two objects but I got this error. I don't know how to mapping property ID from object MyUserAccount to object Book. ID is a String data received from Google (I'm doing Social Login in my project).
Error
PreparedStatementCallback; SQL [INSERT INTO Books(TENSACH, TACGIA, NHANXET, TINHTRANG, THELOAI, IMAGE, IMAGE_NAME) VALUES ( ?, ?, ?, ?, ?, ?, ?)]; Field 'ID' doesn't have a default value; nested exception is java.sql.SQLException: Field 'ID' doesn't have a default value
BookDao (How I save object Book into database)
public void save(Book book) {
// TODO Auto-generated method stub
KeyHolder keyHolder = new GeneratedKeyHolder();
String sql = "INSERT INTO Books(TENSACH, TACGIA, NHANXET, TINHTRANG, THELOAI, IMAGE, IMAGE_NAME) "
+ "VALUES ( :tensach, :tacgia, :nhanxet, :tinhtrang, :theloai, :image, :image_name)";
namedParameterJdbcTemplate.update(sql, getSqlParameterByModel(book), keyHolder);
book.setBook_ID(keyHolder.getKey().intValue());
}
private SqlParameterSource getSqlParameterByModel(Book book) {
MapSqlParameterSource paramSource = new MapSqlParameterSource();
paramSource.addValue("book_id", book.getBook_ID());
paramSource.addValue("tensach", book.getTensach());
paramSource.addValue("tacgia", book.getTacgia());
paramSource.addValue("nhanxet", book.getNhanxet());
paramSource.addValue("tinhtrang", book.getTinhtrang());
paramSource.addValue("image", book.getImage());
paramSource.addValue("image_name", book.getImage_name());
paramSource.addValue("theloai", book.getTheloai());
return paramSource;
}
Model Book
public class Book implements Serializable {
private static final long serialVersionUID = 1L;
private Integer book_ID;
private String tensach;
private String tacgia;
private String nhanxet;
private String tinhtrang;
private String theloai;
private byte[] image;
private String image_name;
private String data;
private MyUserAccount myUserAccount;
public Book() {
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "ID", nullable = false)
public MyUserAccount getMyUserAccount() {
return this.myUserAccount;
}
public void setMyUserAccount(MyUserAccount myUserAccount) {
this.myUserAccount = myUserAccount;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "book_id", unique = true, nullable = false)
public Integer getBook_ID() {
return book_ID;
}
#Column(name = "image_name")
public String getImage_name() {
return image_name;
}
#Column(name = "tensach", length = 50, nullable = true)
public String getTensach() {
return tensach;
}
#Lob
#Type(type = "org.hibernate.type.BinaryType")
#Column(name = "image", columnDefinition = "LONGBLOB", nullable = true)
public byte[] getImage() {
return image;
}
#Column(name = "tacgia", length = 50, nullable = true)
public String getTacgia() {
return tacgia;
}
#Column(name = "nhanxet", length = 100, nullable = true)
public String getNhanxet() {
return nhanxet;
}
#Column(name = "tinhtrang", length = 50, nullable = true)
public String getTinhtrang() {
return tinhtrang;
}
#Column(name = "theloai", length = 50, nullable = true)
public String getTheloai() {
return theloai;
}
#Column(name = "data", length = 16777215)
public String getData() {
return data;
}
public void setBook_ID(Integer book_ID) {
this.book_ID = book_ID;
}
public void setImage_name(String image_name) {
this.image_name = image_name;
}
public void setImage(byte[] image) {
this.image = image;
}
public void setTensach(String tensach) {
this.tensach = tensach;
}
public void setTacgia(String tacgia) {
this.tacgia = tacgia;
}
public void setNhanxet(String nhanxet) {
this.nhanxet = nhanxet;
}
public void setTinhtrang(String tinhtrang) {
this.tinhtrang = tinhtrang;
}
public void setTheloai(String theloai) {
this.theloai = theloai;
}
public void setData(String data) {
this.data = data;
}
#Override
public String toString() {
return "Book [book_ID=" + book_ID + ", tensach=" + tensach + ", tacgia=" + tacgia + ", nhanxet=" + nhanxet
+ ", tinhtrang=" + tinhtrang + ", theloai=" + theloai + ", image=" + Arrays.toString(image) + "]";
}
}
Model MyUserAccount.
public class MyUserAccount implements Serializable {
private static final long serialVersionUID = 1L;
public static final String ROLE_USER = "ROLE_USER";
private String id;
private String email;
private String userName;
private String firstName;
private String lastName;
private String password;
private String role;
private String enabled;
private List<Book> book = new ArrayList<Book>(0);
public MyUserAccount() {
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "myUserAccount")
public List<Book> getBook() {
return book;
}
public void setBook(List<Book> book) {
this.book = book;
}
public MyUserAccount(String id, String email, String userName, String firstName, //
String lastName, String password, String role, String enabled) {
this.id = id;
this.email = email;
this.userName = userName;
this.firstName = firstName;
this.lastName = lastName;
this.password = password;
this.role = role;
this.enabled = enabled;
}
#Id
#Column(name = "ID", unique = true, nullable = false)
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
#Column(name = "EMAIL", unique = true, nullable = false)
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
#Column(name = "USER_NAME", unique = true, nullable = false)
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
#Column(name = "FIRST_NAME", nullable = false)
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
#Column(name = "LAST_NAME", nullable = false)
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
#Column(name = "PASSWORD", nullable = false)
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#Column(name = "ROLE", nullable = false)
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
#Column(name = "ENABLED", columnDefinition = "VARCHAR(1) default 'Y'", nullable = false)
public String getEnabled() {
return enabled;
}
public void setEnabled(String enabled) {
this.enabled = enabled;
}
}
Controller
#RequestMapping(value = "/motsach/add/", method = RequestMethod.POST)
public String saveBook(#ModelAttribute("bookForm") #Validated Book book, BindingResult result, Model model,
#RequestParam CommonsMultipartFile[] image, String userName, final RedirectAttributes redirectAttributes)
throws IOException, UnsupportedEncodingException {
MyUserAccount myUserAccount = myUserAccountDAO.findByUserName(userName);
System.out.println(userName + "sssssssssssss");
book.setMyUserAccount(myUserAccount);
redirectAttributes.addFlashAttribute("css", "success");
if (book.getBook_ID() == null) {
System.out.println(book.getBook_ID());
redirectAttributes.addFlashAttribute("msg", "book added successfully!");
} else {
redirectAttributes.addFlashAttribute("msg", "book updated successfully!");
}
for (CommonsMultipartFile aFile : image) {
System.out.println("Saving file: " + aFile.getOriginalFilename());
book.setImage_name(aFile.getOriginalFilename());
book.setImage(aFile.getBytes());
System.out.println("Damn that Shit!");
}
bookService.saveOrUpdate(book);
// POST/REDIRECT/GET
return "redirect:/motsach/" + book.getBook_ID();
}
You have a #manyToOne (with ID as name ) relation that can't be null. So in order to add a book you have to set MyUserAccount to a book before saving or you can turn into :
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "ID", nullable = true)
public MyUserAccount getMyUserAccount() {
return this.myUserAccount;
}
and modify your column in your database to set the possibility of null value.

Declaring class is not found in the inheritance state hierarchy: UserAccount

I'm using servlets with JPA+Hibernate). I don't understand the error, unless I've tried other solutions suggested in this forum. In fact, I don't want to store the UserAccount class as an entity; but I just want to declare it in the Utilisateur class (the Ids of the Utilisateur class are declared in the useraccount class).
My code :
#Entity
#Table(name = "utilisateur")
public class Utilisateur implements Serializable {
#Id
private UserAccount userAccount;
private Civility civility;
private Address address;
private Contact contact;
#Column(name = "sessions")
private List<String> sessions;
#Column(name = "particularRules")
private boolean particularRules;
public Utilisateur(UserAccount pAccount, Civility pCivility,
Address pAddress, Contact pContact, List<String>
pSessions,
boolean particularRules) {
this.userAccount = pAccount;
this.civility = pCivility;
this.address = pAddress;
this.contact = pContact;
this.sessions = pSessions;
this.particularRules = particularRules;
}
public Civility getCivility() {
return civility;
}
public void setCivility(Civility civility) {
this.civility = civility;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public Contact getContact() {
return contact;
}
public void setContact(Contact contact) {
this.contact = contact;
}
public boolean isParticularRules() {
return particularRules;
}
public void setParticularRules(boolean particularRules) {
this.particularRules = particularRules;
}
public UserAccount getUserAccount() {
return userAccount;
}
public void setUserAccount(UserAccount userAccount) {
this.userAccount = userAccount;
}
public List<String> getSessions() {
return sessions;
}
public void setSessions(List<String> sessions) {
this.sessions = sessions;
}
}
#Embeddable
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class UserAccount implements Serializable {
public UserAccount() {
}
public UserAccount(String pId, String pEmail, String pwsd, Date pCreaDate, Date pLastModDate) {
this.identifier = pId;
this.email = pEmail;
this.password = pwsd;
this.creationDate = pCreaDate;
this.lastModificationDate = pLastModDate;
}
#OneToOne(mappedBy = "userAccount", cascade = CascadeType.ALL,
fetch = FetchType.EAGER, orphanRemoval = true, targetEntity =
Utilisateur.class)
private Utilisateur user;
#Column(name = "creationDate")
#Temporal(javax.persistence.TemporalType.DATE)
private Date creationDate;
#Column(name = "lastModificationDate")
#Temporal(javax.persistence.TemporalType.DATE)
private Date lastModificationDate;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "identifier", nullable = false)
private String identifier;
#Column(name = "email")
private String email;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "password", nullable = false)
private String password;
public String getIdentifier() {
return identifier;
}
public void setIdentifier(String identifier) {
this.identifier = identifier;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
public Date getLastModificationDate() {
return lastModificationDate;
}
public void setLastModificationDate(Date lastModificationDate) {
this.lastModificationDate = lastModificationDate;
}
public Utilisateur getUser() {
return user;
}
public void setUser(Utilisateur user) {
this.user = user;
}
}
You must use an Embedded Primary Key.
See the answer to this question here in Stackoverflow How to create and handle composite primary key in JPA.
Best regards!
It may occur when Embedded Primary Key contains #EmbeddedId. Sub-composite key should be annotated with #Embedded instead.

Hibernate custom ordering and java.text.Collator

I need to sort a Result set depending on a field by asc or dsc order. That field is of type String and contains names of users. Now the names are french name. So to sort list of users based on their names generally I use the following code:
final Collator collator = Collator.getInstance(Locale.FRANCE);
Comparator<ActivityUserDTO> comparator = new Comparator<ActivityUserDTO>() {
#Override
public int compare(ActivityUserDTO dto1, ActivityUserDTO dto2) {
return collator.compare(dto1.getFullName(), dto2.getFullName());
}
};
Collections.sort(users, comparator);
In this case I have the whole list of users loaded from Database and then I am doing the soring.
Now following code is for hibernate where I have startIndex: which sets the FirstResult for Criteria, maxResult: which sets the MaxResults of Criteria and the ordering:
Criteria criteria = getSessionFactory().getCurrentSession().createCriteria(entityClass);
if (StringUtils.isNotEmpty(sortField)) {
criteria.addOrder(sortOrder ? Order.asc(sortField) : Order.desc(sortField));
}
criteria.setFirstResult(startIndex);
criteria.setMaxResults(maxResult);
Here the sortField is fullName which is in French and sortOrder can be either true or false.
Is there any way to make the ordering in custom manner so that it do the sorting/ordering which is done by the Collator? Any pointer would be very helpful to me.
I have seen some site like:
Documentation
Sorting Hibernate Set using a comparator
Hibernate annotations sort using Comparator
where they are using Comparator to sort the Set of Assoicated Objects, but how can I do it in my case?
This is my User:
#javax.persistence.Entity
#Table(name = "USER")
public class User extends Entity {
#Transient
private static final long serialVersionUID = -112950002831333869L;
private String username;
private String firstName;
private String lastName;
private String fullName;
private String mail;
private String homePostalAddress;
private String mobile;
private String homePhone;
private Date dateOfBirth;
private Date dateOfJoining;
private Date dateOfRelease;
private boolean active;
private String role;
private Set<Activity> activities;
public User() {
super();
}
#NaturalId
#Column(name = "USERNAME", nullable = false)
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
#Column(name = "FIRST_NAME")
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
#Column(name = "LAST_NAME")
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
#Column(name = "FULL_NAME")
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
#Column(name = "MAIL")
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
#Column(name = "HOME_POSTAL_ADDRESS")
public String getHomePostalAddress() {
return homePostalAddress;
}
public void setHomePostalAddress(String homePostalAddress) {
this.homePostalAddress = homePostalAddress;
}
#Column(name = "MOBILE")
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
#Column(name = "HOME_PHONE")
public String getHomePhone() {
return homePhone;
}
public void setHomePhone(String homePhone) {
this.homePhone = homePhone;
}
#Column(name = "DATE_OF_BIRTH")
public Date getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(Date dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
#Column(name = "DATE_OF_JOINING")
public Date getDateOfJoining() {
return dateOfJoining;
}
public void setDateOfJoining(Date dateOfJoining) {
this.dateOfJoining = dateOfJoining;
}
#Column(name = "DATE_OF_RELEASE")
public Date getDateOfRelease() {
return dateOfRelease;
}
public void setDateOfRelease(Date dateOfRelease) {
this.dateOfRelease = dateOfRelease;
}
#Column(name = "ACTIVE", nullable = false)
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
#Column(name = "ROLE")
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
#ManyToMany(cascade = { CascadeType.ALL }, mappedBy = "users", targetEntity = Activity.class)
public Set<Activity> getActivities() {
return activities;
}
public void setActivities(Set<Activity> activities) {
this.activities = activities;
}
}
Hibernate doesn't do the sorting. The database does. Executing a criteria query boils down to executing a SQL query having an order by fullName clause.
So check the configuration of your database to know how to specify the collation used by a table or column.
ALTER DATABASE adb DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
did the job.

Persisting OneToMany relationship only persists first object in set?

Been messing around with Hibernate and PostgreSQL trying to get it to work as expected.
But for some reason when I try to persist an object with a #OneToMany relationship with more than one item in the set all but the first item seem to be ignored. I've tried this via local and remote interfaces but get the same results each time. No exceptions are thrown, it looks like hibernate just stops persisting after the first unit has been persisted.
Any help much appreciated this one has been eluding me for days now.
I'm using Hibernate 3.5 and PostgreSQL 8.4.4 with Glassfish v3. All the annotations in the source are from the package javax.persistence - had to remove imports because of the character limit.
The FacadeManager is simply a utility to take the hassle out of jndi lookups, it simplifies accessing remote facades.
Here is the test method
#Test
public void testOneToManyCascade() throws Exception {
/*
* Set up entities requred to perform the test
*/
UnitFacadeRemote unitfr = FacadeManager
.getFacade(UnitFacadeRemote.class);
UserFacadeRemote userfr = FacadeManager
.getFacade(UserFacadeRemote.class);
User user = new User("P", "P", "000000", true, new Date(), "ypy#ypy",
"wordof mout", "slacker", "password");
Address address = new Address("yo", "go", "YOKO", "4123");
address.setCountry(FacadeManager.getFacade(CountryFacadeRemote.class)
.find(2));
user.setAddress(address);
Unit unit1 = new Unit(1, "Test Unit1", new Date(), "DisService",
"MyNation");
Unit unit2 = new Unit(2, "Test Unit2", new Date(), "DisService",
"TheirNation");
Unit unit3 = new Unit(3, "Test Unit3", new Date(), "DisService",
"TheirNation");
// Check no game exists
assertThat(FacadeManager.getFacade(GameFacadeRemote.class).findAll()
.size(), is(0));
Game game = new Game("blabla", 3333, "A game!", true);
// Create game and return reference to persisted game instance
game = FacadeManager.getFacade(GameFacadeRemote.class).registerGame(
game);
unit1.setGame(game);
unit2.setGame(game);
unit3.setGame(game);
// Find a virtue
Virtue v = FacadeManager.getFacade(VirtueFacadeRemote.class).find(1);
unit1.setVirtue(v);
unit2.setVirtue(v);
unit3.setVirtue(v);
// check that none of the above exist already
assertThat(userfr.findAll().size(), is(0));
assertThat(unitfr.findAll().size(), is(0));
/*
* Try persisting the by cascading from the user
*/
Set<Unit> unitSet = new HashSet<Unit>();
unitSet.add(unit2);
unitSet.add(unit1);
unitSet.add(unit3);
user.setUnitSet(unitSet);
unit1.setUser(user);
unit2.setUser(user);
unit3.setUser(user);
// Persist
userfr.create(user);
/*
* The result of the preceding persist is that the game, user, address
* and one unit are persisted, in this case unit2 but it seems whichever
* unit is first added to unitSet is the one that is persisted.
*/
}
Here follow the various entity classes
package com.game.database.entity;
#Entity
#Table(name = "address")
#NamedQueries({
#NamedQuery(name = "Address.findAll", query = "SELECT a FROM Address a"),
#NamedQuery(name = "Address.findById", query = "SELECT a FROM Address a WHERE a.id = :id"),
#NamedQuery(name = "Address.findByLine1", query = "SELECT a FROM Address a WHERE a.line1 = :line1"),
#NamedQuery(name = "Address.findByLine2", query = "SELECT a FROM Address a WHERE a.line2 = :line2"),
#NamedQuery(name = "Address.findByCity", query = "SELECT a FROM Address a WHERE a.city = :city"),
#NamedQuery(name = "Address.findByAreaCode", query = "SELECT a FROM Address a WHERE a.areaCode = :areaCode") })
public class Address implements Serializable {
private static final long serialVersionUID = 1L;
#SequenceGenerator(name = "address_id_seq", sequenceName = "address_id_seq", allocationSize = 1)
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "address_id_seq")
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#Basic(optional = false)
#Column(name = "line1")
private String line1;
#Basic(optional = false)
#Column(name = "line2")
private String line2;
#Basic(optional = false)
#Column(name = "city")
private String city;
#Basic(optional = false)
#Column(name = "areaCode")
private String areaCode;
#JoinColumn(name = "country", referencedColumnName = "id")
#ManyToOne(optional = false)
private Country country;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "address")
private Set<User> userSet;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "address")
private Set<CardDetails> cardDetailsSet;
public Address() {
}
public Address(Integer id) {
this.id = id;
}
public Address(String line1, String line2, String city, String areaCode) {
this.line1 = line1;
this.line2 = line2;
this.city = city;
this.areaCode = areaCode;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLine1() {
return line1;
}
public void setLine1(String line1) {
this.line1 = line1;
}
public String getLine2() {
return line2;
}
public void setLine2(String line2) {
this.line2 = line2;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getAreaCode() {
return areaCode;
}
public void setAreaCode(String areaCode) {
this.areaCode = areaCode;
}
public Country getCountry() {
return country;
}
public void setCountry(Country country) {
this.country = country;
}
public Set<User> getUserSet() {
return userSet;
}
public void setUserSet(Set<User> userSet) {
this.userSet = userSet;
}
public Set<CardDetails> getCardDetailsSet() {
return cardDetailsSet;
}
public void setCardDetailsSet(Set<CardDetails> cardDetailsSet) {
this.cardDetailsSet = cardDetailsSet;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are
// not set
if (!(object instanceof Address)) {
return false;
}
Address other = (Address) object;
if ((this.id == null && other.id != null)
|| (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "com.game.database.entity.Address[id=" + id + "]";
}
}
--
package com.game.database.entity;
#Entity
#Table(name = "game")
#NamedQueries({
#NamedQuery(name = "Game.findAll", query = "SELECT g FROM Game g"),
#NamedQuery(name = "Game.findById", query = "SELECT g FROM Game g WHERE g.id = :id"),
#NamedQuery(name = "Game.findByHost", query = "SELECT g FROM Game g WHERE g.host = :host"),
#NamedQuery(name = "Game.findByPort", query = "SELECT g FROM Game g WHERE g.port = :port"),
#NamedQuery(name = "Game.findByDescription", query = "SELECT g FROM Game g WHERE g.description = :description"),
#NamedQuery(name = "Game.findByActive", query = "SELECT g FROM Game g WHERE g.active = :active"),
#NamedQuery(name = "Game.findByHostAndPort", query = "SELECT g FROM Game g WHERE g.host = :host AND g.port = :port") })
public class Game implements Serializable {
private static final long serialVersionUID = 1L;
#SequenceGenerator(name = "game_id_seq", sequenceName = "game_id_seq", allocationSize = 1)
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "game_id_seq")
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#Basic(optional = false)
#Column(name = "host")
private String host;
#Basic(optional = false)
#Column(name = "port")
private int port;
#Basic(optional = false)
#Column(name = "description")
private String description;
#Basic(optional = false)
#Column(name = "active")
private Boolean active;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "game")
private Set<Unit> unitSet;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "game")
private Set<Payment> paymentSet;
public Game() {
}
public Game(Integer id) {
this.id = id;
}
public Game(String host, int port, String description, Boolean active) {
this.host = host;
this.port = port;
this.description = description;
this.active = active;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Boolean getActive() {
return active;
}
public void setActive(Boolean active) {
this.active = active;
}
public Set<Unit> getUnitSet() {
return unitSet;
}
public void setUnitSet(Set<Unit> unitSet) {
this.unitSet = unitSet;
}
public Set<Payment> getPaymentSet() {
return paymentSet;
}
public void setPaymentSet(Set<Payment> paymentSet) {
this.paymentSet = paymentSet;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are
// not set
if (!(object instanceof Game)) {
return false;
}
Game other = (Game) object;
if ((this.id == null && other.id != null)
|| (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "com.game.database.entity.Game[id=" + id + "]";
}
}
--
package com.game.database.entity;
#Entity
#Table(name = "unit")
#NamedQueries({
#NamedQuery(name = "Unit.findAll", query = "SELECT u FROM Unit u"),
#NamedQuery(name = "Unit.findById", query = "SELECT u FROM Unit u WHERE u.id = :id"),
#NamedQuery(name = "Unit.findByUnitId", query = "SELECT u FROM Unit u WHERE u.unitId = :unitId"),
#NamedQuery(name = "Unit.findByName", query = "SELECT u FROM Unit u WHERE u.name = :name"),
#NamedQuery(name = "Unit.findByRegistrationDate", query = "SELECT u FROM Unit u WHERE u.registrationDate = :registrationDate"),
#NamedQuery(name = "Unit.findByService", query = "SELECT u FROM Unit u WHERE u.service = :service"),
#NamedQuery(name = "Unit.findByNation", query = "SELECT u FROM Unit u WHERE u.nation = :nation") })
public class Unit implements Serializable {
private static final long serialVersionUID = 1L;
#SequenceGenerator(name = "unit_id_seq", sequenceName = "unit_id_seq", allocationSize = 1)
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "unit_id_seq")
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#Basic(optional = false)
#Column(name = "unitId")
private Integer unitId;
#Basic(optional = false)
#Column(name = "name")
private String name;
#Basic(optional = false)
#Column(name = "registrationDate")
#Temporal(TemporalType.TIMESTAMP)
private Date registrationDate;
#Basic(optional = false)
#Column(name = "service")
private String service;
#Basic(optional = false)
#Column(name = "nation")
private String nation;
#JoinColumn(name = "virtue", referencedColumnName = "id")
#ManyToOne(optional = false)
private Virtue virtue;
#JoinColumn(name = "customer", referencedColumnName = "id")
#ManyToOne(optional = false)
private User customer;
#JoinColumn(name = "game", referencedColumnName = "id")
#ManyToOne(optional = false)
private Game game;
public Unit() {
}
public Unit(Integer id) {
this.id = id;
}
public Unit(Integer unitId, String name, Date registrationDate,
String service, String nation) {
this.unitId = unitId;
this.name = name;
this.registrationDate = registrationDate;
this.service = service;
this.nation = nation;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getUnitId() {
return unitId;
}
public void setUnitId(Integer unitId) {
this.unitId = unitId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getRegistrationDate() {
return registrationDate;
}
public void setRegistrationDate(Date registrationDate) {
this.registrationDate = registrationDate;
}
public String getService() {
return service;
}
public void setService(String service) {
this.service = service;
}
public String getNation() {
return nation;
}
public void setNation(String nation) {
this.nation = nation;
}
public Virtue getVirtue() {
return virtue;
}
public void setVirtue(Virtue virtue) {
this.virtue = virtue;
}
public User getUser() {
return customer;
}
public void setUser(User user) {
this.customer = user;
}
public Game getGame() {
return game;
}
public void setGame(Game game) {
Logger.getLogger("org.hibernate").setLevel(Level.FINEST);
this.game = game;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are
// not set
if (!(object instanceof Unit)) {
return false;
}
Unit other = (Unit) object;
if ((this.id == null && other.id != null)
|| (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "com.game.database.entity.Unit[id=" + id + "]";
}
#Transient
private String command;
/**
* Get the value of command
*
* #return the value of command
*/
public String getCommand() {
return command;
}
/**
* Set the value of command
*
* #param command
* new value of command
*/
public void setCommand(String command) {
this.command = command;
}
#Transient
private String rank;
/**
* Get the value of rank
*
* #return the value of rank
*/
public String getRank() {
return rank;
}
/**
* Set the value of rank
*
* #param rank
* new value of rank
*/
public void setRank(String rank) {
this.rank = rank;
}
#Transient
private BigDecimal price;
/**
* Get the value of price
*
* #return the value of price
*/
public BigDecimal getPrice() {
return price;
}
/**
* Set the value of price
*
* #param price
* new value of price
*/
public void setPrice(BigDecimal price) {
this.price = price;
}
}
--
package com.game.database.entity;
#Entity
#Table(name = "customer")
#NamedQueries({
#NamedQuery(name = "User.findAll", query = "SELECT u FROM User u"),
#NamedQuery(name = "User.findById", query = "SELECT u FROM User u WHERE u.id = :id"),
#NamedQuery(name = "User.findByGivenName", query = "SELECT u FROM User u WHERE u.givenName = :givenName"),
#NamedQuery(name = "User.findBySurname", query = "SELECT u FROM User u WHERE u.surname = :surname"),
#NamedQuery(name = "User.findByPhoneNumber", query = "SELECT u FROM User u WHERE u.phoneNumber = :phoneNumber"),
#NamedQuery(name = "User.findBySex", query = "SELECT u FROM User u WHERE u.sex = :sex"),
#NamedQuery(name = "User.findByBirthYear", query = "SELECT u FROM User u WHERE u.birthYear = :birthYear"),
#NamedQuery(name = "User.findByEmail", query = "SELECT u FROM User u WHERE u.email = :email"),
#NamedQuery(name = "User.findByInfoSource", query = "SELECT u FROM User u WHERE u.infoSource = :infoSource"),
#NamedQuery(name = "User.findByOccupation", query = "SELECT u FROM User u WHERE u.occupation = :occupation"),
#NamedQuery(name = "User.findByPassword", query = "SELECT u FROM User u WHERE u.password = :password"),
#NamedQuery(name = "User.findByEmailAndPassword", query = "SELECT u FROM User u WHERE u.password = :password AND u.email = :email") })
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#SequenceGenerator(name = "user_id_seq", sequenceName = "user_id_seq", allocationSize = 1)
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_id_seq")
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#Basic(optional = false)
#Column(name = "givenName")
private String givenName;
#Basic(optional = false)
#Column(name = "surname")
private String surname;
#Basic(optional = false)
#Column(name = "phoneNumber")
private String phoneNumber;
#Basic(optional = false)
#Column(name = "sex")
private boolean sex;
#Basic(optional = false)
#Column(name = "birthYear")
#Temporal(TemporalType.DATE)
private Date birthYear;
#Basic(optional = false)
#Column(name = "email")
private String email;
#Basic(optional = false)
#Column(name = "infoSource")
private String infoSource;
#Basic(optional = false)
#Column(name = "occupation")
private String occupation;
#Basic(optional = false)
#Column(name = "password")
private String password;
/**
* The EAGER fetch type ensures that when we get access a unit remotely it
* has had its unit set initialised and populated
*/
#OneToMany(cascade = CascadeType.ALL, mappedBy = "customer", fetch = FetchType.EAGER)
private Set<Unit> unitSet;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "customer", fetch = FetchType.EAGER)
private Set<Payment> paymentSet;
#JoinColumn(name = "address", referencedColumnName = "id")
#ManyToOne(cascade = CascadeType.ALL, optional = false)
private Address address;
public User() {
}
public User(Integer id) {
this.id = id;
}
public User(String givenName, String surname, String phoneNumber,
boolean sex, Date birthYear, String email, String infoSource,
String occupation, String password) {
this.givenName = givenName;
this.surname = surname;
this.phoneNumber = phoneNumber;
this.sex = sex;
this.birthYear = birthYear;
this.email = email;
this.infoSource = infoSource;
this.occupation = occupation;
this.password = password;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getGivenName() {
return givenName;
}
public void setGivenName(String givenName) {
this.givenName = givenName;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public boolean getSex() {
return sex;
}
public void setSex(boolean sex) {
this.sex = sex;
}
public Date getBirthYear() {
return birthYear;
}
public void setBirthYear(Date birthYear) {
this.birthYear = birthYear;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getInfoSource() {
return infoSource;
}
public void setInfoSource(String infoSource) {
this.infoSource = infoSource;
}
public String getOccupation() {
return occupation;
}
public void setOccupation(String occupation) {
this.occupation = occupation;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Set<Unit> getUnitSet() {
return unitSet;
}
public void setUnitSet(Set<Unit> unitSet) {
this.unitSet = unitSet;
}
public Set<Payment> getPaymentSet() {
return paymentSet;
}
public void setPaymentSet(Set<Payment> paymentSet) {
this.paymentSet = paymentSet;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are
// not set
if (!(object instanceof User)) {
return false;
}
User other = (User) object;
if ((this.id == null && other.id != null)
|| (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "com.game.database.entity.User[id=" + id + "]";
}
}
--
package com.game.database.entity;
#Entity
#Table(name = "virtue")
#NamedQueries({
#NamedQuery(name = "Virtue.findAll", query = "SELECT v FROM Virtue v"),
#NamedQuery(name = "Virtue.findById", query = "SELECT v FROM Virtue v WHERE v.id = :id"),
#NamedQuery(name = "Virtue.findByName", query = "SELECT v FROM Virtue v WHERE v.name = :name"),
#NamedQuery(name = "Virtue.findByDescription", query = "SELECT v FROM Virtue v WHERE v.description = :description") })
public class Virtue implements Serializable {
private static final long serialVersionUID = 1L;
#SequenceGenerator(name = "virtue_id_seq", sequenceName = "virtue_id_seq", allocationSize = 1)
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "virtue_id_seq")
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#Basic(optional = false)
#Column(name = "name")
private String name;
#Basic(optional = false)
#Column(name = "description")
private String description;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "virtue")
private Set<Unit> unitSet;
public Virtue() {
}
public Virtue(Integer id) {
this.id = id;
}
public Virtue(String name, String description) {
this.name = name;
this.description = description;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Set<Unit> getUnitSet() {
return unitSet;
}
public void setUnitSet(Set<Unit> unitSet) {
this.unitSet = unitSet;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are
// not set
if (!(object instanceof Virtue)) {
return false;
}
Virtue other = (Virtue) object;
if ((this.id == null && other.id != null)
|| (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "com.game.database.entity.Virtue[id=" + id + "]";
}
}
You have a problem with the identity of the Unit objects. You're using in your code a HashSet which relies on equals and hashCode methods which are overridden in your code.
If you run the main method in the code below, you will see that after adding the Unit objects there is only one of them in the set (I reused your original code but I simplified it a bit):
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
public class Unit {
private Integer id;
private Integer unitId;
private String name;
private Date registrationDate;
private String service;
private String nation;
public Unit() {
}
public Unit(Integer id) {
this.id = id;
}
public Unit(Integer unitId, String name, Date registrationDate, String service, String nation) {
this.unitId = unitId;
this.name = name;
this.registrationDate = registrationDate;
this.service = service;
this.nation = nation;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getUnitId() {
return unitId;
}
public void setUnitId(Integer unitId) {
this.unitId = unitId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getRegistrationDate() {
return registrationDate;
}
public void setRegistrationDate(Date registrationDate) {
this.registrationDate = registrationDate;
}
public String getService() {
return service;
}
public void setService(String service) {
this.service = service;
}
public String getNation() {
return nation;
}
public void setNation(String nation) {
this.nation = nation;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Unit)) {
return false;
}
Unit other = (Unit) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "com.game.database.entity.Unit[id=" + id + "]";
}
public static void main(String... args) {
Unit unit1 = new Unit(1, "Test Unit1", new Date(), "DisService", "MyNation");
Unit unit2 = new Unit(2, "Test Unit2", new Date(), "DisService", "TheirNation");
Unit unit3 = new Unit(3, "Test Unit3", new Date(), "DisService", "TheirNation");
Set unitSet = new HashSet();
unitSet.add(unit2);
unitSet.add(unit1);
unitSet.add(unit3);
System.out.println(unitSet.size());
}
If you comment out the equals() and hashCode() and run the code again you will see three objects in the set.
Your equals() method is based on the id property which is set by hibernate at time the object is being persisted and not at the time of adding to the set. It means that the Unit has always a null id and hashCode = 0 when added to the set. I recommend reading this article: http://community.jboss.org/wiki/EqualsandHashCode
Hope it helps!

Categories