[hibernate-issues] [Hibernate-JIRA] Commented: (HSEARCH-662) Re-indexing failure in @IndexedEmbedded entities in @ManyToOne relationship

Guillaume Smet (JIRA) noreply at atlassian.com
Tue Aug 9 13:25:05 EDT 2011


    [ http://opensource.atlassian.com/projects/hibernate/browse/HSEARCH-662?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=43199#comment-43199 ] 

Guillaume Smet commented on HSEARCH-662:
----------------------------------------

Hello,

I confirm that this is a real bug and here is an explanation and a proposal on how to fix it.

The problem is that in the WorkPlan, works are stored by id in the map:
{code}
private final HashMap<Serializable, PerEntityWork<T>> entityById = new HashMap<Serializable, PerEntityWork<T>>().
{code}

This id is extracted using the extractProperId() method which is:
{code}
                 private Serializable extractProperId(Work<T> work) {
			T entity = work.getEntity();
			// 1) entity is null for purge operation, which requires to trust the work id
			// 2) types mapped as provided id require to use the work id
			// 3) when Hibernate identifier rollback is used && this identifier is our same id source, we need to get the value from work id
			if ( entity == null ||
					documentBuilder.requiresProvidedId() ||
					( work.isIdentifierWasRolledBack() && documentBuilder.isIdMatchingJpaId() )
					) {
				return work.getId();
			}
			else {
				return documentBuilder.getId( entity );
			}
		}
{code}

In the case explained above, we are in the "return documentBuilder.getId( entity );" case and the documentBuilder is a DocumentBuilderContainedEntity which returns null as the id:
{code}
        @Override
	public Serializable getId(Object entity) {
		//this is not an indexed entity
		return null;
	}
{code}

So for all the @ContainedIn entities, the id is null and when you add a new one in the queue, it overwrites the previous one and thus you have only one entity reindexed.

I think the easiest way to fix the problem is to also return work.getId() in the case of @ContainedIn entities. IMHO, I would test if documentBuilder.getId( entity ) returns null and, if so, I would return the work.getId(). It's the most solid solution on the long term, rather than special casing the @ContainedIn case.

Something along these lines should fix it:

{code}
                 private Serializable extractProperId(Work<T> work) {
			T entity = work.getEntity();
			// 1) entity is null for purge operation, which requires to trust the work id
			// 2) types mapped as provided id require to use the work id
			// 3) when Hibernate identifier rollback is used && this identifier is our same id source, we need to get the value from work id
			if ( entity == null ||
					documentBuilder.requiresProvidedId() ||
					( work.isIdentifierWasRolledBack() && documentBuilder.isIdMatchingJpaId() )
					) {
				return work.getId();
			}
			else {
				Serializable id = documentBuilder.getId( entity );
                                if ( id != null ) {
                                        return id;
                                } else {
                                        return work.getId();
                                }
			}
		}
{code}

Feel free to ask any further question if my explanation isn't clear. It would be nice to have it fixed in the next version of Hibernate Search.

-- 
Guillaume

> Re-indexing failure in @IndexedEmbedded entities in @ManyToOne relationship
> ---------------------------------------------------------------------------
>
>                 Key: HSEARCH-662
>                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HSEARCH-662
>             Project: Hibernate Search
>          Issue Type: Bug
>          Components: engine
>    Affects Versions: 3.3.0.Final
>         Environment: Hibernate 3.6.0
>            Reporter: Kyrill Alyoshin
>            Priority: Blocker
>         Attachments: hibernate_search_bug.zip
>
>
> What is happening seems to be this:
> Let's say we have an @Indexed entity called Son. It has @IndexedEmbedded parent property called Dad in @ManyToOne relationship. Dad is @ContainedIn and has @Field on one of its fields. I am demonstrating a condition when more than one Dads are updated in a single session, only one would be re-indexed, the rest will fail to be re-indexed.
> I am attaching a simple IDEA project that clearly demonstrates what is going on. I believe that this is a very serious bug. (Note: I removed hibernate-3.6.0.jar from the lib directory to minimize the size of the zip file under 10M, the rest of the jars are there).
> Please run BugDemonstrationTest#showBug test method to see everything. 

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the hibernate-issues mailing list