[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-3113) Problem when adding a new Object in unidirectional one-to-many and change the hashCode value of others objects of the collection
Claudio (JIRA)
noreply at atlassian.com
Mon Feb 25 21:51:34 EST 2008
[ http://opensource.atlassian.com/projects/hibernate/browse/HHH-3113?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_29582 ]
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.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
More information about the hibernate-issues
mailing list