标签: hibernate-criteria

如何在不使用任何数据库的情况下测试Hibernate条件查询?

我正在开发一个包含大量复杂Hibernate标准查询的Java应用程序.我想测试这些标准,以确保他们选择正确的,只有正确的对象.当然,其中一种方法是建立内存数据库(例如HSQL),并在每次测试中使用条件对该数据库进行往返,然后断言查询结果符合我的期望.

但我正在寻找一个更简单的解决方案,因为Hibernate标准只是一种关于Java对象的特殊逻辑谓词.因此,理论上,它们可以在不访问任何数据库的情况下进行测试.例如,假设有一个名为的实体Cat:

class Cat {
    Cat(String name, Integer age){
        this.name = name;
        this.age = age;
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

我想做这样的事情来创建条件查询:

InMemoryCriteria criteria = InMemoryCriteria.forClass(Cat.class)
   .add(Restrictions.like("name", "Fritz%"))
   .add(Restrictions.or(
      Restrictions.eq("age", new Integer(0)),
      Restrictions.isNull("age")))

assertTrue(criteria.apply(new Cat("Foo", 0)))
assertTrue(criteria.apply(new Cat("Fritz Lang", 12)))
assertFalse(criteria.apply(new Cat("Foo", 12)))
Run Code Online (Sandbox Code Playgroud)

标准可以在生产代码中使用,如下所示:

criteria.getExecutableCriteria(session); //similar to DetachedCriteria
Run Code Online (Sandbox Code Playgroud)

是否有任何Java库可以进行此类测试?

unit-testing hibernate-criteria

10
推荐指数
1
解决办法
1万
查看次数

Criteria.DISTINCT_ROOT_ENTITY不会阻止重复的对象

我有以下dao方法:

@Override
public List<AdminRole> findAll() {
    Session session = sessionFactory.getCurrentSession();
    Criteria criteria = session.createCriteria(AdminRole.class);
    criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
    return criteria.list();
}
Run Code Online (Sandbox Code Playgroud)

实际上我想从数据库中检索所有条目.

有时我看到重复.当我使用AdminRole添加用户时会发生这种情况.

我已经读过,当我使用EAGERfetch类型时,这是可能的,这应该是修复添加以下行:

criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
Run Code Online (Sandbox Code Playgroud)

但这对我没有帮助.

我的映射:

@Entity
@Table(name = "terminal_admin_role")
public class AdminRole {

    @Id
    @Column(name = "role_id", nullable = false, unique = true)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_id")
    @SequenceGenerator(name = "user_id", sequenceName = "user_id")
    private Long adminId;

    @Column(name = "role")
    private String role;

    public AdminRole(String role) {
        this.role = role;
    }

    public AdminRole() {
    }

    // get set …
Run Code Online (Sandbox Code Playgroud)

java orm hibernate criteria hibernate-criteria

10
推荐指数
1
解决办法
1075
查看次数

Hibernate Criteria查询问题与投影和限制

我试图使用hibernate条件查询从表中选择列

Criteria cr = session.createCriteria(OfferCashbackMaster.class)
    .setProjection(Projections.projectionList()
      .add(Projections.property("txnType"), "txnType")
      .add(Projections.property("off_Discription"), "off_Discription"))
    .setResultTransformer(Transformers.aliasToBean(OfferCashbackMaster.class))
    .add(Restrictions.and(Restrictions.eq("aggregatorId", aggregatorId),
                           Restrictions.eq("txnType", txnType)));
Run Code Online (Sandbox Code Playgroud)

txnType投影中提到的名称与限制发生冲突.

给我以下错误

Hibernate: 
select 
    this_.OFFER_CODE as y0_, 
    this_.TXN_TYPE as y1_, 
    this_.VALID_TO as y2_, 
    this_.OFFER_DISCRIPTION as y3_ 
    from OFFER_CASHBACK_MASTER this_ 
where 
    (this_.AGGREGATOR_ID=? and y1_=?)

2018-02-25/15:42:41.756  WARN: util.JDBCExceptionReporter - 
SQL Error: 1054, SQLState: 42S22
2018-02-25/15:42:41.757 ERROR: util.JDBCExceptionReporter - 
Unknown column 'y1_' in 'where clause'
Run Code Online (Sandbox Code Playgroud)

我们如何解决这个问题?

java hibernate criteria hibernate-criteria

10
推荐指数
2
解决办法
609
查看次数

org.hibernate.sql.ast.SqlTreeCreationException:无法找到TableGroup - model.dao.User(1055362627602899)

我有一个 spring boot 2.7.5 和 hibernate 5.6.12 项目,我想升级到 spring boot 3.1.0 和 hibernate 6.6.2 我正在尝试数据库中的查询计数以获取数据库中的记录总数,我得到错误

org.hibernate.sql.ast.SqlTreeCreationException:无法在 org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.prepareReusablePath(BaseSqmToSqlAstConverter.java:3349) ~[hibernate-core- 6.2.2.Final.jar:6.2.2.Final]

基类是:

public class JPADaoImpl {
    protected final Logger logger = LoggerFactory.getLogger(getClass());
    
    @Autowired
    @Qualifier("dataSource")
    protected DataSource dataSource;
    
    @PersistenceContext
    protected EntityManager entityManager;
    
    protected <T> PageData<T> getPageData(CriteriaQuery<T> criteria,Root<T> root,Integer pStart, Integer pSize,LockModeType lockModeType) throws Exception{
        PageData<T> pageData =null;
        try {
            pageData = new PageData<T>();
            
            criteria.distinct(true);
            
            criteria.select(root);
            
            TypedQuery<T> query = getPersistenceQuery(criteria, pStart, pSize, lockModeType);
            
            if (pStart == null || pSize == null) {
                pageData.setData(query.getResultList());
                return …
Run Code Online (Sandbox Code Playgroud)

hibernate hibernate-criteria spring-boot

10
推荐指数
1
解决办法
3529
查看次数

如何使用Criteria API指定悲观锁定?

我正在使用Criteria API检索hibernate中的对象列表.但是我需要锁定这些对象,因为同时执行的另一个线程将获得确切的对象,并且只有一个线程将在没有悲观锁定的情况下成功.

我尝试过如下,但它不起作用.

List esns = session
    .createCriteria(Reddy_Pool.class)
    .add(Restrictions.eq("status", "AVAILABLE"))
    .add(Restrictions.eq("name", "REDDY2"))
    .addOrder(Order.asc("id"))
    .setMaxResults(n)
    .setLockMode(LockMode.PESSIMISTIC_WRITE) //not working at all
    .list();
Run Code Online (Sandbox Code Playgroud)

更新:我在此语句之后执行更新,因此我希望两个线程都读取不同的行,或者至少第二个线程应该等到第一个线程完成事务并离开锁.

而hibernate生成的查询如下.

Hibernate: select this_.id as id1_0_, this_.name as name1_0_, 
this_.orderitem_id as orderitem3_1_0_, this_.status as status1_0_, 
this_.store as store1_0_, this_.vendor as vendor1_0_, this_.version as version1_0_ 
from reddy_pool this_ 
where this_.status=? and and this_.name=? order by this_.id asc limit ?
Run Code Online (Sandbox Code Playgroud)

更新:这似乎是3.5.2版本中的一个错误,因为Pascal Thivent(非常感谢Pascal)提到过,我已经加入成为会员并观看了这个问题.希望它将包含在下一个版本中.

然而,我尝试使用另一种方法session.buildLockRequest()...但我无法弄清楚如何使用它并使用下面的代码根本没有任何影响.

for (int i=0; i < n; i++)
    session.buildLockRequest(LockOptions.UPGRADE).lock(esns.get(i));
Run Code Online (Sandbox Code Playgroud)

hibernate hibernate-criteria

9
推荐指数
1
解决办法
7645
查看次数

我何时或为何使用Property.forName()?

有什么区别:

List cats = session.createCriteria(Cat.class)  
.add( Restrictions.like("name", "F%")
.list();   
Run Code Online (Sandbox Code Playgroud)

List cats = session.createCriteria(Cat.class)  
.add( Property.forName("name").like("F%") )  
.list(); 
Run Code Online (Sandbox Code Playgroud)

或者就此而言,区别在于:

Criteria cr = session.createCriteria(User.class)
    .setProjection(Projections.projectionList() 
    .add(Property.forName("id").as("id")) 
    .add(Property.forName("name").as("name"))
Run Code Online (Sandbox Code Playgroud)

Criteria cr = session.createCriteria(User.class)
    .setProjection(Projections.projectionList()
    .add(Projections.property("id"), "id")
    .add(Projections.property("Name"), "Name"))
Run Code Online (Sandbox Code Playgroud)

hibernate hibernate-criteria

9
推荐指数
1
解决办法
5691
查看次数

按条件查询获取第一行表

如何通过使用criteriaHQL查询获取表的第一行?

表创建脚本

   CREATE TABLE MonthlySubscriber(MSISDN bigint(20) 
   NOT NULL, MonthOfYear int(11) NOT NULL, 
   PRIMARY KEY (MSISDN)); 
Run Code Online (Sandbox Code Playgroud)

hibernate hql hibernate-criteria

9
推荐指数
1
解决办法
3万
查看次数

Hibernate标准连接表问题

我有3个实体,如下所示.我想写一个提取产品的查询.在此查询中,参数是optionValues id的列表.

现在我的问题是如何加入这些实体?

产品:

 public class Product{
   //other col

    @OneToMany(mappedBy = "product")
    private Set<Attribute> attributeSet = new HashSet<>();
 }
Run Code Online (Sandbox Code Playgroud)

属性:

public class Attribute{
  @OneToOne
  @JoinColumn(name = "OPTION_VALUE_ID")
  private OptionValue optionValue;

  @ManyToOne
  @JoinColumn(name="PRODUCT_ID",referencedColumnName="id")
  private Product product;
}
Run Code Online (Sandbox Code Playgroud)

optionValue:

 public class OptionValue{
     @Column(name = "id")
     private Long id;

    @Column(name = "value",updatable = true)
    private String value;
 }
Run Code Online (Sandbox Code Playgroud)

我写了一个查询,但我认为我的代码不是一个好的解决方案.

 Criteria aCriteria = null;
    if (!optionValueList.isEmpty()) {
        aCriteria = currentSession().createCriteria(Attribute.class, "attribute");
        aCriteria.createAlias("attribute.optionValue", "optionValue");
        aCriteria.add(Restrictions.in("optionValue.id", optionValueList));
        attributes = aCriteria.list();
    }
    PagingData<Product> pagingData = new PagingData<>(); …
Run Code Online (Sandbox Code Playgroud)

java hibernate jointable hibernate-criteria

9
推荐指数
1
解决办法
877
查看次数

Spring JPA ExampleMatcher 比较日期条件

我正在使用 Spring JPA 并使用 Example Matcher 获取数据列表。源代码如下:

public Page<TranxLog> findAllByConditions(TranxReportFormModel formModel, Pageable page) {
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withNullHandler(ExampleMatcher.NullHandler.IGNORE)
                .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING)
                .withIgnoreCase()
                .withIgnoreNullValues();
        Example<TranxLog> example = Example.of(formModel.getTranxLog(), matcher);
        return tranxlogRepository.findAll(example, page);
    }
Run Code Online (Sandbox Code Playgroud)

现在,我的搜索页面,其中有formDatetoDate它有与现场相比较DateTimeTranxLog。我尝试使用.withMatcher()但找不到比较日期的方法。

任何的想法?谢谢。

spring hibernate query-by-example hibernate-criteria spring-data-jpa

9
推荐指数
2
解决办法
6673
查看次数

如何使用旧的休眠标准进行批处理?

我仍在使用旧的org.hibernate.Criteria,并且对获取模式越来越困惑。在各种查询中,我需要以下所有变体,因此我无法通过注释来控制它。我只是将所有内容都切换到@ManyToOne(fetch=FetchType.LAZY),否则,查询中的任何内容都没有更改。

到目前为止我能找到的要么涉及 HQL 或 JPA2,要么只提供两种选择,但对于旧标准和(至少)以下三种情况,我需要它:

  • 执行 JOIN,并从两个表中获取。除非数据过于冗余(例如,主数据很大或在结果中重复多次),否则这是可以的。在 SQL 中,我会写
    SELECT * FROM item JOIN order on item.order_id = order.id
    WHERE ...;
  • 执行 JOIN,从第一个表中获取,并与另一个表分离。这通常是前一个查询的更有效的变体。在 SQL 中,我会写
    SELECT item.* FROM item JOIN order on item.order_id = order.id
    WHERE ...;

    SELECT order.* FROM order WHERE ...;
  • 执行 JOIN,但不获取连接的表。这很有用,例如,对于基于另一个表的数据进行排序。在 SQL 中,我会写
    SELECT item.* FROM item JOIN order on item.order_id = order.id
    WHERE ...
    ORDER BY order.name, item.name;

看起来没有明确指定fetch=FetchType.LAZY,一切都会像第一种情况一样急切地获取,这有时太糟糕了。我想,使用Criteria#setFetchMode,我可以获得第三种情况。我还没有尝试过,因为我仍然错过了第二个案例。我知道,它在某种程度上可能,还有的@BatchSize标注。

  • 我对上面的说法正确吗?
  • 有没有办法如何使用旧标准获得第二个案例? …

java performance hibernate join hibernate-criteria

9
推荐指数
1
解决办法
338
查看次数