The trick is to use a count:
select i from Item i join i.tags twhere t in :tags group by i.id having count(i.id) = :tagCount
I just had the same problem as you. I used the reductio ad absurdum:
select distinct i from Item i where i not in (select i2 from Item i2 join i2.tags t where t not in :tags)