-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 11 posts ] 
Author Message
 Post subject: Problem with composite key
PostPosted: Wed Nov 05, 2008 2:54 pm 
Newbie

Joined: Wed Oct 22, 2008 5:22 pm
Posts: 7
I have composite key in a legacy table, the indexing is fine (I have field bridge to index the composite id), but a strange thing is happening I am not sure whether it’s a bug on the Hibernate side. When there is more than one search result the query returns nothing I have enabled query out put I can see this query

(I have omitted the select part of the query)
….
….
where
this_.discriminator='D'
and (
(
this_.id, this_.docVersion
) in (
(
?, ?
), (
?, ?
)
)
)

The composite key is id + docVersion. I can get a result if there is one search result for this scenario the generated query looks like below

….
where
this_.discriminator='D'
and (
(
this_.id, this_.docVersion
) in (
(
?, ?
)
)
)

So if there is more than one values in the IN clause the query returns nothing.

Thanks for your valuable answer


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 06, 2008 7:57 am 
Hibernate Team
Hibernate Team

Joined: Thu Apr 05, 2007 5:52 am
Posts: 1689
Location: Sweden
Hi,

it is hard to give any advice with the given information. You have to provide the actual mapped/annotated classes, how you index them and how you search. Some more log output would be helpful as well.

--Hardy


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 06, 2008 11:14 am 
Newbie

Joined: Wed Oct 22, 2008 5:22 pm
Posts: 7
hardy,

here is the code snippets

***********************Begin****************************

Question
-----------
public class Question implements Serializable {

@Field(index = Index.TOKENIZED, store = Store.YES)
private String statement;

....
....
....
@IndexedEmbedded
private Set<Tag> tags;

@EmbeddedId
@DocumentId
@FieldBridge(impl = QuestionPKBridge.class)
private QuestionPK questionPK;

....
....
}


Tag
-------
@Indexed
public class Tag implements Serializable {
@DocumentId
private Long id;
...
...
...
@ContainedIn
private Set<Question> questions;

}


Primary key class
------------------
@Embeddable
public class QuestionPK implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private Double questionVersion;

public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Double getQuestionVersion() {
return questionVersion;
}
public void setQuestionVersion(Double questionVersion) {
this.questionVersion = questionVersion;
}
@Override
public boolean equals(Object obj) {
boolean equal = false;

if ((obj == null) || !(obj instanceof QuestionPK)) {
equal = false;
} else if (obj == this) {
equal = true;
} else {
QuestionPK otherKey = (QuestionPK) obj;
equal = ((otherKey.id.longValue() == this.id.longValue()) && (otherKey.questionVersion.doubleValue() == this.questionVersion.doubleValue()));
}

return equal;
}
@Override
public int hashCode() {
int hashCode = id.hashCode() + questionVersion.hashCode();

return hashCode;
}
}


Field bridge Implementation
---------------------------

public class QuestionPKBridge implements TwoWayFieldBridge {
public Object get(String fieldName, Document doc) {
QuestionPK questionPK = new QuestionPK();
Field field = null;
field = doc.getField(fieldName + ".id");
questionPK.setId(new Long(field.stringValue()));
field = doc.getField(fieldName + ".questionVersion");
questionPK.setQuestionVersion(new Double(field.stringValue()));

return questionPK;
}
public String objectToString(Object obj) {
QuestionPK questionPK = (QuestionPK) obj;
StringBuilder sb = new StringBuilder();
sb.append(questionPK.getId()).append(" ").append(questionPK.getQuestionVersion());

return sb.toString();
}
public void set(String fieldName, Object obj, Document doc, Store store, Index index, Float boost) {
QuestionPK questionPK = (QuestionPK) obj;
Field field = new Field(fieldName + ".id", String.valueOf(questionPK.getId()), store, index);

if (boost != null) {
field.setBoost(boost);
}

doc.add(field);

field = new Field(fieldName + ".questionVersion", String.valueOf(questionPK.getQuestionVersion()), store, index);

if (boost != null) {
field.setBoost(boost);
}

doc.add(field);
}
}

Mappings
----------
Question
--------
<class name="Question" table="clear_question" optimistic-lock="version" discriminator-value="Q">
<composite-id name="questionPK" class="QuestionPK" >
<key-property name="id" type="long" column="id"/>
<key-property name="questionVersion" type="double" column="questionVersion"/>
</composite-id>
<discriminator column="discriminator" type="character" />

<set name="tags" table="question_to_tag" lazy="true" cascade="all">
<key >
<column name="questionId"/>
<column name="questionVersion"/>
</key>
<many-to-many column="tagId" class="Tag" />
</set>

<subclass name="DescriptiveQuestion" extends="Question" discriminator-value="D">
<set name="suggestedAnswers" lazy="true" cascade="all">
<key>
<column name="questionId" />
<column name="questionVersion" />
</key>
<one-to-many class="QuestionAnswer" />
</set>
</subclass>
...
...
...
</class>

Tag
-----
<hibernate-mapping>
<class name="Tag" table="clear_tag" optimistic-lock="version">

<id name="id" unsaved-value="null">
<generator class="native" />
</id>
<version name="version" type="long" />
<property name="createdOn" type="timestamp" />
<property name="name" />
<set name="questions" table="question_to_tag" lazy="true" cascade="all">
<key column="tagId" />
<many-to-many class="Question" >
<column name="questionId"/>
<column name="questionVersion"/>
</many-to-many>
</set>
</class>
</hibernate-mapping>

Test indexing code snippet
------------------------

public void indexDescriptiveQuestions() {
HibernateCallback callback = new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException, SQLException {
FullTextSession fullTextSession = Search.createFullTextSession(session);
List<DescriptiveQuestion> questions = session.createQuery("SELECT question FROM DescriptiveQuestion as question LEFT JOIN FETCH question.tags").list();

for (DescriptiveQuestion question : questions) {
fullTextSession.index(question);
}

return null;
}
};

getHibernateTemplate().execute(callback);
}



***********************End****************************


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 21, 2008 12:59 pm 
Newbie

Joined: Fri Nov 21, 2008 12:43 pm
Posts: 3
I have exactly the same problem.
In the example given here, if there are suppose 2 records to be fetched with id,version as (id1,version1) and (id2,version2) then the generated query will be

….
where
this_.discriminator='D'
and (
(
this_.id, this_.docVersion
) in (
(
id1, id2
), (
version1, version2
)
)
)


instead of the correct query as ..

….
where
this_.discriminator='D'
and (
(
this_.id, this_.docVersion
) in (
(
id1, version1
), (
id2, version2
)
)
)


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 21, 2008 1:51 pm 
Hibernate Team
Hibernate Team

Joined: Thu Apr 05, 2007 5:52 am
Posts: 1689
Location: Sweden
Hi,

which version of Hibernate Search are you using? This might have been a bug, but should be fixed in the latest versions of Hibernate Search.

--Hardy


Top
 Profile  
 
 Post subject:
PostPosted: Sat Nov 22, 2008 9:09 am 
Newbie

Joined: Fri Nov 21, 2008 12:43 pm
Posts: 3
Hi,
I tried with both 3.0.1 and 3.1.0 but its the same problem. The values passed to the query are not in the proper expected order.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Nov 23, 2008 4:03 am 
Hibernate Team
Hibernate Team

Joined: Thu Apr 05, 2007 5:52 am
Posts: 1689
Location: Sweden
Hi,

maybe you could open a jira issue for that and maybe even attach a testcase. That would be much appreciated and help a lot to get to the bottom of this.

--Hardy


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 24, 2008 2:27 pm 
Newbie

Joined: Fri Nov 21, 2008 12:43 pm
Posts: 3
Hi,
I have opened a jira issue for this and also attached my source code.

http://opensource.atlassian.com/project ... SEARCH-306

Thanks. Hoping this problem will get resolved soon.


Top
 Profile  
 
 Post subject: I have same problem with composite key
PostPosted: Wed Feb 25, 2009 10:35 am 
Newbie

Joined: Mon Mar 14, 2005 11:54 am
Posts: 6
The query printed out below used in Luke works fine and gives me 5 hits - BUT in my test case in hibernate search I get only 1 hit.

The Query I use in Luke is the exact one printed out from logger below. I use the same StandarAnalyzer in Luke an in my code.
Code:
MultiFieldQueryParser parser = new MultiFieldQueryParser(fields, new StandardAnalyzer());
org.apache.lucene.search.Query query = parser.parse(queryString);
logger.info( "Lucene query string :" + query.toString() );



In the Hibernate Search log I see it finds one but then :
[main] org.hibernate.search.engine.ObjectLoaderHelper - Object found in Search index but not in database: class ch...... CK[868980,3]
..


This is a unfortunately a showstopper if there is no workaround.



Kind regards
Georges


Top
 Profile  
 
 Post subject: Workaround for this..
PostPosted: Thu Feb 26, 2009 1:47 pm 
Newbie

Joined: Mon Mar 14, 2005 11:54 am
Posts: 6
I managed to get around this problem by using projections and getting the compositekey from the index and then doing a regular load using a generic dao.

Projections are great and really blazes in performance since you might opt to not query for more data after you got your index hits (with the composite keys). For me it was 5 times faster (depends on your entity and mappings and index size)


Kind regards
Georges


Top
 Profile  
 
 Post subject: Source code
PostPosted: Wed Mar 04, 2009 3:34 pm 
Newbie

Joined: Wed Mar 04, 2009 3:33 pm
Posts: 1
Can you post the source code to the work around you found? I've hit this same issue and confirmed it hasn't been fixed in the most current version of the code.

Thanks

Kris


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 11 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.