Hi,
I have a domain object that has a composite identifier and I'm having trouble retrieving the objects from the database, despite getting hits from the Search index. I'm using Hibernate Search annotations with Hibernate XML mappings.
I'm seeing this warning in the log:
[DEBUG] 17:17:39 ObjectLoaderHelper - Object found in Search index but not in database: class com.test.schema.entities.Course with Key: id1 - id2
Where "Key: id1 - id2" is the toString() method of the CoursePK object - indicating that the CoursePK is loaded correctly from the index - the values of the composite id are correct and match those in the database.
I'm able to call sessionFactory.getCurrentSession().load(Course.class, pk) on any given Course id and get the correct result.
I'm really confused as to why this is happening and can only assume it is a configuration issue. Any help would be appreciated.
Here are the Objects / mappings (I've removed most of the unnecessary code):
Course Object:
Code:
@Indexed
public class Course implements Cloneable, Serializable
{
@DocumentId
@FieldBridge(impl = CoursePKBridge.class)
private CoursePK id;
etc...
}
CoursePK Object:
Code:
public class CoursePK implements Serializable
{
String courseCode;
String vendorCode;
public CoursePK() {
super();
}
[getters and setters]
@Override
public boolean equals(Object other)
{
if ( !(other instanceof CoursePK) ) return false;
CoursePK castOther = (CoursePK) other;
return new EqualsBuilder()
.append(this.getCourseCode(), castOther.getCourseCode())
.append(this.getVendorCode(), castOther.getVendorCode())
.isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder()
.append(getCourseCode()+getVendorCode())
.toHashCode();
}
}
CoursePKBridge:
Code:
public class CoursePKBridge implements TwoWayFieldBridge
{
public Object get(String name, Document document)
{
CoursePK id = new CoursePK();
Field field = document.getField( name + ".courseCode" );
id.setCourseCode( field.stringValue() );
field = document.getField( name + ".vendorCode" );
id.setVendorCode( field.stringValue() );
return id;
}
public String objectToString(Object object)
{
CoursePK id = (CoursePK) object;
StringBuilder sb = new StringBuilder();
sb.append( id.getCourseCode() )
.append( id.getVendorCode() );
return sb.toString();
}
public void set(String name, Object value, Document document, LuceneOptions luceneOptions)
{
CoursePK id = (CoursePK) value;
Store store = luceneOptions.getStore();
Index index = luceneOptions.getIndex();
TermVector termVector = luceneOptions.getTermVector();
Float boost = luceneOptions.getBoost();
//store each property in a unique field
Field field = new Field( name + ".courseCode", id.getCourseCode(), store, index, termVector );
field.setBoost( boost );
document.add( field );
field = new Field( name + ".vendorCode", id.getVendorCode(), store, index, termVector );
field.setBoost( boost );
document.add( field );
//store the unique string representation in the named field
field = new Field( name, objectToString( id ), store, index, termVector );
field.setBoost( boost );
document.add( field );
}
}
Course XML Mapping:
Code:
<class name="Course" table="course" batch-size="30" dynamic-insert="true" dynamic-update="true" >
<cache usage="read-write"/>
<composite-id name="id" class="com.test.schema.entities.CoursePK">
<key-property name="courseCode" column="course_code" />
<key-property name="vendorCode" column="vendor_code_fk" />
</composite-id>
[property mappings...]
</class>