Hi,
I'd like to report a couple bugs with Composite keys in Hibernate 3.5.6
1) EAGER/JOIN fetch does not supported.
2) Components of a Composite key cannot be used in Criteria, because Hibernate does not create JOIN for them
I have 2 beans, one is used a as part of a composite key of the second bean.
Full sample (included source code and DB script).
hibernate3.5.6bug_2.zipCode:
@Entity @Table(name="preference")
public class Preference implements Serializable {
private static final long serialVersionUID = 1L;
private String id;
private String defaultValue;
@GenericGenerator(name="generator", strategy="uuid.hex", parameters = { } )
@Id @GeneratedValue(generator="generator")
@Column(name="id", unique=false, nullable=false, insertable=true, updatable=true)
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Column(name="default_value", unique=false, nullable=true, insertable=true, updatable=true)
public String getDefaultValue() {
return defaultValue;
}
public void setDefaultValue(String defaultValue) {
this.defaultValue = defaultValue;
}
}
Code:
@Embeddable
public class UserPreferenceKey implements Serializable {
private static final long serialVersionUID = 1L;
private String userId;
private Preference preference;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="preference_id", unique=false, nullable=true, insertable=true, updatable=true)
public Preference getPreference() {
return preference;
}
public void setPreference(Preference preference) {
this.preference = preference;
}
@Column(name="user_id")
public String getUserId() {
return userId;
}
public void setUserId(String uid) {
this.userId = uid;
}
}
Code:
@Entity @Table(name="user_preference")
public class UserPreference implements Serializable {
private static final long serialVersionUID = 1L;
private UserPreferenceKey id;
private String userValue;
@EmbeddedId
public UserPreferenceKey getId() {
return id;
}
public void setId(UserPreferenceKey id) {
this.id = id;
}
@Column(name="user_value", unique=false, nullable=true, insertable=true, updatable=true)
public String getUserValue() {
return userValue;
}
public void setUserValue(String userValue) {
this.userValue = userValue;
}
}
Test code:
Code:
session.createCriteria(UserPreference.class).list();
Output SQL
Code:
select
this_.preference_id as preference3_1_0_,
this_.user_id as user1_1_0_,
this_.user_value as user2_1_0_
from
user_preference this_[/quote]
select
preference0_.id as id0_0_,
preference0_.default_value as default2_0_0_
from
preference preference0_
where
preference0_.id=?
Expected results - everything is fetched in one SQL request
Test 2
Code:
session.createCriteria(UserPreference.class)
.setFetchMode("id.preference", FetchMode.JOIN)
.list();
Output SQL - same, like Test 1. Expected results - everything is fetched in one SQL request
Test 3
Code:
session.createCriteria(UserPreference.class)
.createAlias("id.preference", "d")
.add(Restrictions.eq("d.defaultValue", "DEFAULT"))
.list();
Output SQL
Code:
select
this_.preference_id as preference3_1_0_,
this_.user_id as user1_1_0_,
this_.user_value as user2_1_0_
from
user_preference this_
where
d1_.default_value=?
And exception
Caused by: java.sql.SQLException: The multi-part identifier "d1_.default_value" could not be bound.Expected results - everything is fetched in one SQL request, no errors