/* * Hibernate, Relational Persistence for Idiomatic Java * * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. */ package org.hibernate.test.filter; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; import javax.persistence.Table; import java.sql.Timestamp; import java.util.HashSet; import java.util.List; import java.util.Set; import org.hibernate.annotations.Filter; import org.hibernate.annotations.FilterDef; import org.hibernate.annotations.FilterDefs; import org.hibernate.annotations.Filters; import org.hibernate.annotations.ParamDef; import org.hibernate.query.Query; import org.junit.Before; import org.junit.Test; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import static org.hamcrest.core.Is.is; import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; import static org.junit.Assert.assertThat; /** * @author Andrea Boriero */ public class OneToManyWithDynamicFilterTest extends BaseCoreFunctionalTestCase { @Override protected Class<?>[] getAnnotatedClasses() { return new Class[] {ArticleRevision.class, ArticleTrading.class}; } @Before public void setUp() { doInHibernate( this::sessionFactory, session -> { ArticleTrading articleTrading = new ArticleTrading(); articleTrading.setClassifier( "no_classification" ); articleTrading.setPartyId( 2 ); articleTrading.setDeletionTimestamp( Timestamp.valueOf( "9999-12-31 00:00:00" ) ); articleTrading.setDeleted( true ); ArticleRevision revision = new ArticleRevision(); revision.addArticleTradings( articleTrading ); revision.setDeletionTimestamp( Timestamp.valueOf( "9999-12-31 00:00:00" ) ); revision.setDeleted( true ); session.save( revision ); } ); } @Test public void testForIssue() { doInHibernate( this::sessionFactory, session -> { final org.hibernate.Filter enableFilter = session.enableFilter( "aliveOnly" ); enableFilter.setParameter( "aliveTimestamp", Timestamp.valueOf( "9999-12-31 00:00:00" ) ); enableFilter.setParameter( "deleted", true ); enableFilter.validate(); final Query query = session.createQuery( "select a.id from ArticleRevision as a " + "left join a.articleTradings as t " + "with ( (t.partyId = :p_0) and (t.classifier = :p_1) )" ); query.setParameter( "p_0", 1L ); query.setParameter( "p_1", "no_classification" ); final List list = query.list(); assertThat( list.size(), is( 1 ) ); } ); } @Entity(name = "ArticleRevision") @Table(name = "REVISION") @FilterDefs({ @FilterDef(name = "aliveOnly", parameters = { @ParamDef(name = "aliveTimestamp", type = "timestamp"), @ParamDef(name = "deleted", type = "boolean") }, defaultCondition = "DELETION_TIMESTAMP = :aliveTimestamp and DELETED = :deleted") }) @Filters({@Filter(name = "aliveOnly", condition = "DELETION_TIMESTAMP = :aliveTimestamp and DELETED = :deleted")}) public static class ArticleRevision { @Id @GeneratedValue private long id; @Column(name = "DELETION_TIMESTAMP") private Timestamp deletionTimestamp; @Column(name = "DELETED") private boolean deleted; @OneToMany(mappedBy = "articleRevision", cascade = CascadeType.ALL, fetch = FetchType.LAZY) @Filter(name = "aliveOnly") private Set<ArticleTrading> articleTradings = new HashSet<ArticleTrading>(); public void setDeletionTimestamp(Timestamp deletionTimestamp) { this.deletionTimestamp = deletionTimestamp; } public void setDeleted(boolean deleted) { this.deleted = deleted; } public void addArticleTradings(ArticleTrading articleTrading) { this.articleTradings.add( articleTrading ); articleTrading.setArticleRevision( this ); } } @Entity(name = "ArticleTrading") @Table(name = "TRADING") public static class ArticleTrading { @Id @GeneratedValue private long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "articleRevision", nullable = false) private ArticleRevision articleRevision; private long partyId; private String classifier; @Column(name = "DELETED") private boolean deleted; @Column(name = "DELETION_TIMESTAMP") protected Timestamp deletionTimestamp; public void setArticleRevision(ArticleRevision articleRevision) { this.articleRevision = articleRevision; } public void setPartyId(long partyId) { this.partyId = partyId; } public void setClassifier(String classifier) { this.classifier = classifier; } public void setDeletionTimestamp(Timestamp deletionTimestamp) { this.deletionTimestamp = deletionTimestamp; } public void setDeleted(boolean deleted) { this.deleted = deleted; } } }