JPA Criteria filter not working

I’ve recently posted a thread regarding JPAContainer filters and joins.
I’ve a lot of research I think I’ve worked out how to use a JPA Critera.

I’ve started this new thread as I now think I have found a bug in the JPA Container when using JPA Criteria filters.

So, to set the scene.
I have a table ‘Contact’ which has a many to many join with a table ‘Tag’.


@Entity
class Contact
{
        @Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	protected Long id;

....
        @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
	private Set<Tag> tags = new HashSet<>();
....
}

The entity Tag looks like this:

@Entity
class Tag
{
        @Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	protected Long id;

...
	@Column(unique = true, length = 30)
	String name;
}

I have a Table which is bound to a JPAContainer


public class ContactTable extends Table
{
	private JPAContainer<Contact> contactContainer;
	private String[] visibleColumns;

        ContactTable(JPAContainer<Contact> contactContainer, String[] visibleColumns)
	{
		this.contactContainer = contactContainer;
		this.visibleColumns = visibleColumns;
        	this.setContainerDataSource(contactContainer);
		this.setVisibleColumns((Object[]) visibleColumns);

		this.setSelectable(true);
		this.setImmediate(true);
	}
}

Finally I have a Criteria filter which seems to be generating the right query:


void buildQuery(final Tag tag)
	{
         	contactContainer.removeAllContainerFilters();
		contactContainer.getEntityProvider().setQueryModifierDelegate(new DefaultQueryModifierDelegate()
		{
			@Override
			public void filtersWillBeAdded(CriteriaBuilder cb, CriteriaQuery<?> query, List<Predicate> predicates)
			{
				Root<Contact> fromContact = (Root<Contact>) query.getRoots().iterator().next();
				Join<Contact, Tag> tagJoin = fromContact.join("tags");
				predicates.add(cb.equal(tagJoin.get("id"), tag.getId()));
			}
		});
	}

When I call the buildQuery method I shortly see the following sql code being executed:


SELECT COUNT(t0.ID) FROM CONTACT t0, CONTACT_TAG t2, TAG t1 WHERE ((t1.ID = ?) AND ((t2.Contact_ID = t0.ID) AND (t1.ID = t2.tags_ID)))

This is precisely the correct query and is being called from the table paint logic.

The paint logic looks as if it calls the above query to determine how many rows need painting.
I also see that it determines that it can’t use its own cache due to the existance of the jpa filter.
However I never see it call the above select (sans the ‘count’ clause) to fetch the matching rows.

I’m using Vaadin 7.1.2 and JPAContainer 3.1. The problem was occuring when I was still using JPAContainer 3.0.

Help!

So I worked out how to fix this.

Essentially when the user added a ‘search term’ I was calling my method build query which enabled the jpa query by calling:
setQueryModifierDelegate

Which I thought would have done the trick. But it turns out the table didn’t notice the change (dispite calling the filtered query with a count(*) which returned a changed result.

The trick was to call:
Table.refreshRowCache();

after setting the query and like magic the filter now works.

Yeah!!!