[
http://opensource.atlassian.com/projects/hibernate/browse/HHH-3113?page=c...
]
Claudio commented on HHH-3113:
------------------------------
My hashCode implementation is VALID!
From javadoc:
- Whenever it is invoked on the same object more than once during an execution of a Java
application, the hashCode method must consistently return the same integer, provided no
information used in equals comparisons on the object is modified. This integer need not
remain consistent from one execution of an application to another execution of the same
application. OK
- If two objects are equal according to the equals(Object) method, then calling the
hashCode method on each of the two objects must produce the same integer result. OK
- It is not required that if two objects are unequal according to the
equals(java.lang.Object) method, then calling the hashCode method on each of the two
objects must produce distinct integer results. However, the programmer should be aware
that producing distinct integer results for unequal objects may improve the performance of
hashtables. OK
I reported a bug
Problem when adding a new Object in unidirectional one-to-many and
change the hashCode value of others objects of the collection
-----------------------------------------------------------------------------------------------------------------------------------
Key: HHH-3113
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-3113
Project: Hibernate3
Issue Type: Bug
Components: core
Affects Versions: 3.2.5, 3.2.6
Environment: Hibernate Core 3.2.5.GA, Hibernate Annotations 3.3.0.GA and
Hibernate EntityManager 3.3.1.GA
Mysql Database 5.0
Reporter: Claudio
Priority: Blocker
Attachments: TestOneToMany.zip
My application has two Entities: User and Phone. The User has a unidirectional
one-to-many (join table) with Phone.
The list of my classes:
@Entity
public class User implements Serializable {
private static final long serialVersionUID = 0L;
private Long id;
private Set<Phone> phones = new HashSet<Phone>();
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@OneToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER)
public Set<Phone> getPhones() {
return phones;
}
public void setPhones(Set<Phone> phones) {
this.phones = phones;
}
public void addPhone(Phone p){
if (phones.size()==0) {
// Assert the first phone is main phone
p.setMain(true);
}
else {
// There are others phone
if (p.isMain()){
// Remove the main of others phones
for(Phone temp : phones){
temp.setMain(false);
}
}
}
phones.add(p);
}
public String toString(){
return "User - Set Phones: "+phones;
}
}
@Entity
public class Phone implements Serializable {
private static final long serialVersionUID = 0L;
private Long id;
private String number;
private boolean main;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public boolean isMain() {
return main;
}
public void setMain(boolean main) {
this.main = main;
}
// Overwrite equals
public boolean equals(Object o){
if (this == o) return true;
if (!(o instanceof Phone)) return false;
Phone temp = (Phone)o;
if (!number.equals(temp.getNumber())) return false;
if (main != temp.isMain()) return false;
return true;
}
// Overwrite hashCode
public int hashCode(){
return 29 * number.hashCode() + 29 * (main?1:0);
}
}
When I create the first Phone, call addPhone method of the User and persist the User, the
code works.
But when I create the second Phone and call addphone method of the User, the hashCode
value of the first
Phone change because of the overwrite of hashCode in Phone class. When I persist the User
with two Phones,
the Hibernate try to do two inserts in join table (User_Phone). But the one insert has
been do in first persist
of User. I got this Exception:
Exception in thread "main" javax.persistence.RollbackException: Error while
commiting the transaction
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:71)
at test.Test.mergeUser(Test.java:23)
at test.Test.main(Test.java:59)
Caused by: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC
batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:237)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:144)
at
org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at
org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:54)
... 2 more
Caused by: java.sql.BatchUpdateException: Duplicate entry '1-1' for key 1
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1237)
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:936)
at
com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:1723)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
... 10 more
The Hibernate should do only one insert in table User_Phone. But it tries to do two
inserts. It seems be a bug.
I did a test code. It is attachment in Jira.
I tried to run this code with Hibernate Core 3.2.5.GA and Hibernate Core 3.2.6.GA, but
the problem occurs in both.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira