-->
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.  [ 6 posts ] 
Author Message
 Post subject: HSearch: a complex case of indexing associated objects
PostPosted: Wed Jan 09, 2008 4:19 pm 
Newbie

Joined: Wed Jan 09, 2008 3:28 pm
Posts: 4
Hello,

inspired by Emmanuel's presentation at Javapolis last year, I am currently developing a Hibernate / Hibernate Search based product search app which is supposed to allow queries like this:

"participations.person.name:Miller AND participations.role.name:composer"

The query should return a list of products (like sheet music or CDs) composed by someone called Miller. Another example: query for products having someone called Brown as interpreter.

To do so, I am developing a domain model for an existing product database. It has tables for products, persons and roles as well as one participation mapping table whereat each line ties together the IDs of a product, a person and a role ("crosstable"). These 3 IDs build the composite PK of the table, too.

In the domain model, I have modeled the crosstable as a separate class called ProductParticipation. Its composite key is mapped as an embeddable class called ProductParticipationPK holding the 3 IDs.

Each product has a set of participations, each participation has exactly one person and one role. Persons and roles both have IDs, names and a few more String attributes which shall partly be searchable.

That's what I basically did so far:

Code:
@Entity
@Indexed
class Product {
   ...
   @OneToMany(mappedBy="product")
   @IndexedEmbedded
   Set<ProductParticipation> participations;
   ...
}

@Entity
class ProductParticipation {
    ...
    @EmbeddedId
    ProductParticipationPk id;
   
    @ManyToOne
    @JoinColumn(name="ID_T", insertable=false, updatable=false)
    private Product product;
   
    @ManyToOne
    @JoinColumn(name="ID_PERS", insertable=false, updatable=false)
    @IndexedEmbedded
    private Person person;

    @ManyToOne
    @JoinColumn(name="ID_ROL", insertable=false, updatable=false)
    @IndexedEmbedded
    private ProductParticipationRole role;
    ...
}



The problem is: my test query "participations.person.name:Miller" finds nothing and doesn't even complain about misspelled field names.

These are my questions:

- Is it enough to annotate the Product class with @Indexed or will I have to annotate other classes as Indexed as well?

- How should I annotate the set Product.participations? Is it OK to use @IndexedEmbedded here?

- Does it make sense to use @IndexedEmbedded or @Field annotations inside classes which are not annotated as @Indexed?

- Do I need to use the DocumentId annotation in classes which contain @Field or @IndexedEmbedded annotations, but have no @Indexed annotation?

- Using DocumentId inside ProductParticipation would need a custom TwoWayStringBridge for the composite ID class, right?

- Is it correct to use the ManyToOne associations and the JoinColumn parameters in ProductParticipation like this?

Thank you in advance!
dewoob


Top
 Profile  
 
 Post subject: Re: HSearch: a complex case of indexing associated objects
PostPosted: Wed Jan 09, 2008 7:46 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
dewoob wrote:
The problem is: my test query "participations.person.name:Miller" finds nothing and doesn't even complain about misspelled field names.


I don't understand why this qury returns no object if there is a Miller, at first sight it should.
Not complaining on misspelled field names is a feature to keep the flexibility of Lucene unstructured capability.

Quote:
- Is it enough to annotate the Product class with @Indexed or will I have to annotate other classes as Indexed as well?


It should be enough except for this bug http://opensource.atlassian.com/project ... SEARCH-142

Quote:
- How should I annotate the set Product.participations? Is it OK to use @IndexedEmbedded here?


yes

Quote:
- Does it make sense to use @IndexedEmbedded or @Field annotations inside classes which are not annotated as @Indexed?

yes it can make sense especially on embeddable object but not only.

Quote:
- Do I need to use the DocumentId annotation in classes which contain @Field or @IndexedEmbedded annotations, but have no @Indexed annotation?

no

Quote:
- Using DocumentId inside ProductParticipation would need a custom TwoWayStringBridge for the composite ID class, right?

yes

Quote:
- Is it correct to use the ManyToOne associations and the JoinColumn parameters in ProductParticipation like this?

you mean with isertable=false and updatable=false? Yes that's how I would do it.

Note that if you are looking for a way to check that say Miller is a interpreter and not a composer, ie check on an individual line in the collection, I would do the query differently
I would index ProductParticipation and do a query based on ProductParticipation as a root, retrieve all Product ids and then retrieve the product objects. I know it's less elegant and HSearch should provide a better abstraction in the future, but until then...[/url]

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 10, 2008 7:08 am 
Newbie

Joined: Wed Jan 09, 2008 3:28 pm
Posts: 4
Thank you very much for clearing this up, Emmanuel! Great presentation, btw! Thumbs up!


Top
 Profile  
 
 Post subject: Is this a bug?
PostPosted: Thu Jan 10, 2008 8:57 am 
Newbie

Joined: Wed Jan 09, 2008 3:28 pm
Posts: 4
Finally I solved the problem. It's all a matter of the depth parameter in the IndexedEmbedded annotation:

In Product, I must use:
Code:
class Product {
    ...
    @OneToMany(mappedBy = "product")
    @IndexedEmbedded(depth=2)
    private Set<ProductParticipation> participations;
    ...
}


That should be just as intended, as the reference doc says:
Quote:
"In our example, because depth is set to 1, any @IndexedEmbedded attribute in Owner (if any) will be ignored."

That makes sense for cyclic dependencies, but I in my case it must be set to (at least) 2, otherwise IndexedEmbedded in ProductParticipation will not be incorporated.

There's one thing that I don't understand:
Code:
class ProductParticipation {
    ...
    @ManyToOne
    @JoinColumn(name="ID_PERS", insertable=false, updatable=false)
    @IndexedEmbedded(depth=1)
    private Person person;
   
    @ManyToOne
    @JoinColumn(name="ID_ROL", insertable=false, updatable=false)
    @IndexedEmbedded(depth=1)
    private ProductParticipationRole role;
    ...
}


If I don't set depth=1 (or greater) explicitly, attributes of Person and Role are not included in the index. There seems to be a "depth=0" default behaviour which I disbelieve to be intended. I don't see why I should set depth=1 manually.


Last edited by dewoob on Thu Jan 10, 2008 9:55 am, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 10, 2008 9:03 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
Yes I left a rookie bug slip http://opensource.atlassian.com/projects/hibernate/browse/HSEARCH-140

I plan to release a 3.0.1 sometime soon though.

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 10, 2008 9:12 am 
Newbie

Joined: Wed Jan 09, 2008 3:28 pm
Posts: 4
Ah OK, allrighty then. If this were *not* a bug, that would have been much worse! ;-)


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 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.