Java Hibernate过滤器无效

3

我尝试使用Hibernate过滤器按照insertTime条件获取带有子实体(Filter->Ad)的User实体。我的目标是获得带有在插入时间大于(现在-7天)的广告的用户对象。在测试模式下,我使用内存中的HSQLDB。

但是测试未通过:

getNotOldAds(com.gecars.app.dao.DaoTester) java.lang.AssertionError: expected:<1> but was:<2> ...

测试:

@Before 
public void before() throws ParseException {
    sessionFactory = HibernateUtilTest.getSessionFactory();
    session = sessionFactory.openSession();

    dao = new DAOimpl(session);

    GeUser user = new GeUser();
    user.setId(1);
    Filter filter = new Filter();

    Ad ad = new Ad();
    Ad old = new Ad();

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    Date insertTime = sdf.parse("2015-01-01");

    old.setInsertTime(insertTime);

    filter.addAd(ad);
    filter.addAd(old); // should filter this old ad !!!

    user.addFilter(filter);

    dao.insertUser(user);
}

@Test
public void getNotOldAds() throws Exception{        
    GeUser u = dao.getUser(1);
    assertEquals(1, u.getFilters().size());
    assertEquals(1, u.getFilters().get(0).getAds().size()); // red test !!!
}

用户:

@Entity
@Table(name="users")
public class GeUser {
   ...
   @OneToMany(fetch = FetchType.LAZY, cascade=CascadeType.ALL, mappedBy="user") 
   @OrderBy("id")
   private Set<Filter> filters = new HashSet<Filter>(0);

   public void addFilter(Filter filter){
      this.filters.add(filter);
   }
   ...

筛选器:

@Entity
@Table(name="filters")
@FilterDef(name="time", parameters={
    @ParamDef( name="adTime", type="date" )
})
public class Filter {
   ...
   @ManyToMany(cascade=CascadeType.ALL)
   @FilterJoinTable(name="time", condition=":adTime >= insertTime")
   private Set<Ad> ads; 
   ...

也尝试使用@Filter注释:

@Table(name="filters")
@FilterDef(name="time", parameters={
    @ParamDef( name="adTime", type="date" )
})
public class Filter {
       ...
       @ManyToMany(cascade=CascadeType.ALL)
       @org.hibernate.annotations.Filter(name="time", condition=":adTime >= insertTime"
       private Set<Ad> ads; 
       ...
   )

同时尝试使用类级别的注释,参考此处


@Table(name="filters")
@FilterDef(name="time", parameters={
    @ParamDef( name="adTime", type="date" )
})
@Filters( {
    @org.hibernate.annotations.Filter(name="time", condition=":adTime >= insertTime")
} )
    public class Filter {
           ...
           @ManyToMany(cascade=CascadeType.ALL)
           private Set<Ad> ads; 
           ...
       )

广告:

@Entity
@Table(name="ads")
public class Ad {
   ...
   private Date insertTime = new Date(); // > no less 7 days
   ...

使用DAO方法加载用户:

public GeUser getUser(int id){
    Criteria criteria = session.createCriteria(GeUser.class);
    DateTime dt = new DateTime();

    // set up filter
    session.enableFilter("time").setParameter("adTime", dt.minusDays(7).toDate());

    criteria.add(Restrictions.eq("id",id));
    @SuppressWarnings("unchecked")
    List<GeUser> results = criteria.list();
    if(results.size()<1)return null;
    return results.get(0);
 }

还尝试过以下方法:

public GeUser getUser(int id){
    DateTime dt = new DateTime();
    // enable filter top of createCriteria method
    session.enableFilter("time").setParameter("adTime", dt.minusDays(7).toDate());

    Criteria criteria = session.createCriteria(GeUser.class);
    criteria.add(Restrictions.eq("id",id));
    @SuppressWarnings("unchecked")
    List<GeUser> results = criteria.list();
    if(results.size()<1)return null;
    return results.get(0);

同时,我尝试在创建新查询之前清除会话,但是我得到了 assertEquals(1, u.getFilters().size()); 的底部异常。

java.lang.AssertionError:期望值为 <1>,实际值为 <0>

使用清除会话的DAO方法:

public GeUser getUser(int id){
    this.session.clear();
    DateTime dt = new DateTime();
    session.enableFilter("time").setParameter("adTime", dt.minusDays(7).toDate());
    Criteria criteria = session.createCriteria(GeUser.class);
    criteria.add(Restrictions.eq("id",id));
    @SuppressWarnings("unchecked")
    List<GeUser> results = criteria.list();
    if(results.size()<1)return null;
    return results.get(0);
}

Hibernate日志:
HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
HHH000412: Hibernate Core {4.3.10.Final}
HHH000206: hibernate.properties not found
HHH000021: Bytecode provider name : javassist
HHH000044: Configuring from URL: file:/home/gefalko/git/gecars/WebContent/WEB-INF/classes/hibernate_test.cfg.xml
HHH000223: Recognized obsolete hibernate namespace http://hibernate.sourceforge.net/. Use namespace http://www.hibernate.org/dtd/ instead. Refer to Hibernate 3.6 Migration Guide!
HHH000041: Configured SessionFactory: null
HHH000402: Using Hibernate built-in connection pool (not for production use!)
HHH000401: using driver [org.hsqldb.jdbcDriver] at URL [jdbc:hsqldb:mem:test;sql.enforce_size=false]
HHH000046: Connection properties: {user=car, password=****}
HHH000006: Autocommit mode: false
HHH000115: Hibernate connection pool size: 20 (min=1)
HHH000400: Using dialect: org.hibernate.dialect.HSQLDialect
HHH000399: Using default transaction strategy (direct JDBC transactions)
HHH000397: Using ASTQueryTranslatorFactory
HHH000227: Running hbm2ddl schema export
Hibernate: alter table Filter_meta drop constraint FK_edd3775xix70rbhxbo32wodn4
HHH000389: Unsuccessful: alter table Filter_meta drop constraint FK_edd3775xix70rbhxbo32wodn4
user lacks privilege or object not found: PUBLIC.FILTER_META
Hibernate: alter table ads drop constraint FK_4mfrgdti3fshygqyd6ajyyoxt
HHH000389: Unsuccessful: alter table ads drop constraint FK_4mfrgdti3fshygqyd6ajyyoxt
user lacks privilege or object not found: PUBLIC.ADS
Hibernate: alter table ads drop constraint FK_qm2n3257q8fveo1w82ixtw7f4
HHH000389: Unsuccessful: alter table ads drop constraint FK_qm2n3257q8fveo1w82ixtw7f4
user lacks privilege or object not found: PUBLIC.ADS
Hibernate: alter table filters drop constraint FK_6ona1upsnhrimamvy8vn7brm
HHH000389: Unsuccessful: alter table filters drop constraint FK_6ona1upsnhrimamvy8vn7brm
user lacks privilege or object not found: PUBLIC.FILTERS
Hibernate: alter table filters drop constraint FK_ju0ri0fbfi4y6pls6uu59gucl
HHH000389: Unsuccessful: alter table filters drop constraint FK_ju0ri0fbfi4y6pls6uu59gucl
user lacks privilege or object not found: PUBLIC.FILTERS
Hibernate: alter table filters_ads drop constraint FK_gcri6h0918u8o2ybd6yfquk79
HHH000389: Unsuccessful: alter table filters_ads drop constraint FK_gcri6h0918u8o2ybd6yfquk79
user lacks privilege or object not found: PUBLIC.FILTERS_ADS
Hibernate: alter table filters_ads drop constraint FK_koa5ug12bcrgj2tdnbwfecwjw
HHH000389: Unsuccessful: alter table filters_ads drop constraint FK_koa5ug12bcrgj2tdnbwfecwjw
user lacks privilege or object not found: PUBLIC.FILTERS_ADS
Hibernate: alter table models drop constraint FK_fi4sewhe2m2kvmc49kvlnheat
HHH000389: Unsuccessful: alter table models drop constraint FK_fi4sewhe2m2kvmc49kvlnheat
user lacks privilege or object not found: PUBLIC.MODELS
Hibernate: alter table sources_ads drop constraint FK_gggf7jfe42nh1ivcjj7nt6vmy
HHH000389: Unsuccessful: alter table sources_ads drop constraint FK_gggf7jfe42nh1ivcjj7nt6vmy
user lacks privilege or object not found: PUBLIC.SOURCES_ADS
Hibernate: alter table sources_ads drop constraint FK_rlcr0wrn9f3j92agt0dh7ylin
HHH000389: Unsuccessful: alter table sources_ads drop constraint FK_rlcr0wrn9f3j92agt0dh7ylin
user lacks privilege or object not found: PUBLIC.SOURCES_ADS
Hibernate: alter table users_sources drop constraint FK_l4igmoxgnho61ais4w5em2sro
HHH000389: Unsuccessful: alter table users_sources drop constraint FK_l4igmoxgnho61ais4w5em2sro
user lacks privilege or object not found: PUBLIC.USERS_SOURCES
Hibernate: alter table users_sources drop constraint FK_8roy1p4lpl5aggkq2bucqu211
HHH000389: Unsuccessful: alter table users_sources drop constraint FK_8roy1p4lpl5aggkq2bucqu211
user lacks privilege or object not found: PUBLIC.USERS_SOURCES
Hibernate: drop table Filter_meta if exists
Hibernate: drop table ads if exists
Hibernate: drop table auto if exists
Hibernate: drop table filters if exists
Hibernate: drop table filters_ads if exists
Hibernate: drop table models if exists
Hibernate: drop table sources if exists
Hibernate: drop table sources_ads if exists
Hibernate: drop table users if exists
Hibernate: drop table users_sources if exists
Hibernate: create table Filter_meta (Filter_id integer not null, meta varchar(255), meta_KEY varchar(255) not null, primary key (Filter_id, meta_KEY))
Hibernate: create table ads (id integer generated by default as identity (start with 1), foto varchar(255), fuel_type varchar(50), gearbox varchar(50), insertTime timestamp, price integer, url VARCHAR, year integer, model_id integer, source_id integer, primary key (id))
Hibernate: create table auto (id integer generated by default as identity (start with 1), ebayMake varchar(100), gumtreeMake varchar(100), make varchar(100), primary key (id))
Hibernate: create table filters (id integer generated by default as identity (start with 1), fuel varchar(255), priceFrom integer, priceTo integer, yearFrom integer, yearTo integer, fk_model integer, user integer, primary key (id))
Hibernate: create table filters_ads (filters_id integer not null, ads_id integer not null)
Hibernate: create table models (id integer generated by default as identity (start with 1), autotraderModel varchar(100), ebayModel varchar(100), gumtreeModel varchar(100), mclass varchar(100), model varchar(100), series varchar(100), fk_make integer, primary key (id))
Hibernate: create table sources (id integer generated by default as identity (start with 1), collectClass varchar(100), source varchar(100), primary key (id))
Hibernate: create table sources_ads (sources_id integer not null, ads_id integer not null, primary key (sources_id, ads_id))
Hibernate: create table users (id integer generated by default as identity (start with 1), email varchar(100), primary key (id))
Hibernate: create table users_sources (users_id integer not null, sources_id integer not null, primary key (users_id, sources_id))
Hibernate: alter table sources_ads add constraint UK_gggf7jfe42nh1ivcjj7nt6vmy  unique (ads_id)
Hibernate: alter table Filter_meta add constraint FK_edd3775xix70rbhxbo32wodn4 foreign key (Filter_id) references filters
Hibernate: alter table ads add constraint FK_4mfrgdti3fshygqyd6ajyyoxt foreign key (model_id) references models
Hibernate: alter table ads add constraint FK_qm2n3257q8fveo1w82ixtw7f4 foreign key (source_id) references sources
Hibernate: alter table filters add constraint FK_6ona1upsnhrimamvy8vn7brm foreign key (fk_model) references models
Hibernate: alter table filters add constraint FK_ju0ri0fbfi4y6pls6uu59gucl foreign key (user) references users
Hibernate: alter table filters_ads add constraint FK_gcri6h0918u8o2ybd6yfquk79 foreign key (ads_id) references ads
Hibernate: alter table filters_ads add constraint FK_koa5ug12bcrgj2tdnbwfecwjw foreign key (filters_id) references filters
Hibernate: alter table models add constraint FK_fi4sewhe2m2kvmc49kvlnheat foreign key (fk_make) references auto
Hibernate: alter table sources_ads add constraint FK_gggf7jfe42nh1ivcjj7nt6vmy foreign key (ads_id) references ads
Hibernate: alter table sources_ads add constraint FK_rlcr0wrn9f3j92agt0dh7ylin foreign key (sources_id) references sources
Hibernate: alter table users_sources add constraint FK_l4igmoxgnho61ais4w5em2sro foreign key (sources_id) references sources
Hibernate: alter table users_sources add constraint FK_8roy1p4lpl5aggkq2bucqu211 foreign key (users_id) references users
HHH000230: Schema export complete
Hibernate: insert into users (id, email) values (default, ?)
Hibernate: insert into filters (id, fuel, fk_model, priceFrom, priceTo, user, yearFrom, yearTo) values (default, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into ads (id, foto, fuel_type, gearbox, insertTime, model_id, price, source_id, url, year) values (default, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into ads (id, foto, fuel_type, gearbox, insertTime, model_id, price, source_id, url, year) values (default, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into filters_ads (filters_id, ads_id) values (?, ?)
Hibernate: insert into filters_ads (filters_id, ads_id) values (?, ?)
Hibernate: select this_.id as id1_8_0_, this_.email as email2_8_0_ from users this_ where this_.id=?
Hibernate: select filters0_.user as user8_8_0_, filters0_.id as id1_3_0_, filters0_.id as id1_3_1_, filters0_.fuel as fuel2_3_1_, filters0_.fk_model as fk_model7_3_1_, filters0_.priceFrom as priceFro3_3_1_, filters0_.priceTo as priceTo4_3_1_, filters0_.user as user8_3_1_, filters0_.yearFrom as yearFrom5_3_1_, filters0_.yearTo as yearTo6_3_1_ from filters filters0_ where filters0_.user=? order by filters0_.id

我已经删除了之前的建议作为答案,因为你是对的,它不能解决你的问题。你尝试过这种方法吗?http://www.concretepage.com/hibernate/hibernate-filter-and-filterjointable-annotation-example 在这些示例中,过滤器(和filterjointable)是在实体中定义的,而不是作为一个单独的类。 - RubioRic
我尝试在类级别添加Filter注释,但没有起作用。 - Edgaras Karka
1个回答

4
请使用@Filter代替@FilterJoinTable
@ManyToMany(cascade=CascadeType.ALL)
@Filter(name="time", condition=":adTime >= insertTime")
private Set<Ad> ads; 

文档中得知:
当集合使用关联表作为关系表示时,您可能想将过滤器条件应用于关联表本身或目标实体表。若要在目标实体上应用约束,请使用常规的@Filter注释。但是,如果您想针对关联表进行操作,请使用@FilterJoinTable注释。
其次,在初始设置后,您似乎没有关闭会话,因此您的实体实例仍然在第一级缓存中(这意味着最初具有两个元素的集合仍然在缓存中并从其中返回)。
可以在测试方法中创建新会话,或在执行查询之前清除现有会话。
session.clear();

第三点,看一下这个答案。你需要更新关联的拥有方,反向方(包含mappedBy的那个)没有与数据库同步:
public void addFilter(Filter filter){
    this.filters.add(filter);
    filter.setUser(this);
}

@DrganBozanovic 我尝试清除会话,但现在用户过滤器集的大小为0。请查看编辑后的帖子。 - Edgaras Karka
@EdgarasKarka 请启用SQL日志记录,并发布生成的SQL。 - Dragan Bozanovic
@DrganBozanovi,请查看此帖子。 - Edgaras Karka
@EdgarasKarka 请发布 GeUser 类中 addFilter 方法的实现。 - Dragan Bozanovic
@DrganBozanovi 请查看帖子。 - Edgaras Karka
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接