Hibernate version: JBoss 4.2.2 (Hibernate 3.2.4.sp1, Hibernate EntityManager 3.2.1.GA)
Mapping documents: JPA Annotation + Hibernate Annotation
Name and version of the database you are using: Postgres 8
We have a existing database which has non-nullable column for foreign key. The existing app (non-hibernate) uses 0 to represent null values.
Here is the topic I created for that issue
http://forum.hibernate.org/viewtopic.php?t=988730
I'm using UserType as Identifier of the target entity of the relation to transform 0 to a null value.
Here are the entities :
Code:
@Entity
@Table(name = "notifictation")
public class Notification implements Serializable {
private Long id;
private Transmission completionTx;
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "rowid")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "completiontxid")
public Transmission getCompletionTx() {
return completionTx;
}
public void setCompletionTx(Transmission completionTx) {
this.completionTx = completionTx;
}
}
Code:
@Entity
@Table(name = "transmission")
public class Transmission implements Serializable {
private Long id;
private Date startTime;
private Date endTime;
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "rowid")
@Type(type = "com.mycompany.mapping.util.NullableLongIdUserType")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
Here is the UserType :
Code:
public class NullableLongIdUserType implements UserType {
public int[] sqlTypes() {
return new int[] { Types.BIGINT };
}
public Class<?> returnedClass() {
return Long.class;
}
public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws HibernateException, SQLException {
Long result = resultSet.getLong(names[0]);
return result == null || result.equals(0L) ? null : result;
}
public void nullSafeSet(PreparedStatement statement, Object value, int index) throws HibernateException, SQLException {
statement.setLong(index, value == null ? 0L : (Long) value);
}
public Object deepCopy(Object value) throws HibernateException {
return value;
}
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return cached;
}
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}
public boolean equals(Object x, Object y) throws HibernateException {
return x == y;
}
public boolean isMutable() {
return false;
}
public Object replace(Object original, Object target, Object owner)
throws HibernateException {
return original;
}
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
This works but when I create a Query with "FETCH JOIN" Hibernate produces the correct SQL but still issues a Query (like lazy loading) when I access the relation which has @Type on the ID.
Here is the Query a create :
Code:
select n from Notification n LEFT JOIN FETCH e.completionTx
Again, hibernate produces the correct SQL for that Query,
But it looks like it forgot it has loaded that relation when I access it and then it issues a query to load Transmission.
Any idea ?