Hello,
I have a client mapping having a composite element. Having saved and commited my instance of client, it is resaved in a following transaction. See my code including the logs below.
This does not happen when I use a bag instead of a set. I carefully implemented equal and hashCode and both return identical values in case the deliverAddress contains the same values.
Is this a mistake or am I mistaken?
Best Regards
Sebastian
Code:
Transaction tx = session.beginTransaction();
DeliveryAddress address1 = new DeliveryAddress();
address1.setStreet("Old Street");
address1.setCity("Frankfurt");
Client client = new Client();
client.setName("Carsten");
client.getAddresses().add(address1);
address1.setClient(client);
session.save(client);
tx.commit();
/* log
Hibernate: select nextval ('examples.tclient_id_seq')
Hibernate: insert into examples.tclient (name, id) values (?, ?)
Hibernate: insert into examples.tdeliveryaddress (client_fk, street, city) values (?, ?, ?)
*/
tx = session.beginTransaction();
tx.commit(); // after this commit the values are resaved.
/* log
Hibernate: delete from examples.tdeliveryaddress where client_fk=? and street=? and city=?
Hibernate: insert into examples.tdeliveryaddress (client_fk, street, city) values (?, ?, ?)
*/
Hibernate version: 3.1
<?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 package="de.laliluna.component2">
<class name="Client" table="tclient" >
<id name="id" >
<generator class="sequence">
<param name="sequence" >tclient_id_seq</param>
</generator>
</id>
<property name="name" type="string"></property>
<set name="addresses" table="tdeliveryaddress">
<key column="client_fk"></key>
<composite-element class="DeliveryAddress" >
<property name="street" type="string"></property>
<property name="city" type="string"></property>
</composite-element>
</set>
</class>
</hibernate-mapping>
##########
Code:
package de.laliluna.component2;
public class DeliveryAddress {
private Integer id;
private String street;
private String city;
private Client client;
public Client getClient() {
return client;
}
public void setClient(Client client) {
this.client = client;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
@Override
public boolean equals(Object obj) {
boolean result;
if (!(obj instanceof DeliveryAddress)) // if obj == null then this is
// also false
return false;
if (obj == this)
return true;
DeliveryAddress compareTarget = (DeliveryAddress) obj;
if (compareTarget.client == null){
if (client != null)
return false;
}
else
{
if (client == null)
return false;
else{
if (compareTarget.getClient().getId() == null){
if (client.getId() != null)
return false;
}
else{
if (client.getId() == null)
return false;
else if (compareTarget.getClient().getId() !=client.getId())
return false;
}
}
}
if (!(compareTarget.city == null ? city == null : compareTarget.city
.equals(city)))
return false;
if (!(compareTarget.street == null ? street == null
: compareTarget.street.equals(street)))
return false;
return true;
}
@Override
public int hashCode() {
int result = 17;
if (!(client == null || client.getId() == null))
result = result * 37 + client.getId().hashCode();
if (street != null)
result = result * 37 + street.hashCode();
if (city != null)
result = result * 37 + city.hashCode();
return result;
}
}