我正在开发一个包含大量复杂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库可以进行此类测试?
我有以下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) 我试图使用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)
我们如何解决这个问题?
我有一个 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) 我正在使用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) 有什么区别:
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) 如何通过使用criteria或HQL查询获取表的第一行?
表创建脚本
CREATE TABLE MonthlySubscriber(MSISDN bigint(20)
NOT NULL, MonthOfYear int(11) NOT NULL,
PRIMARY KEY (MSISDN));
Run Code Online (Sandbox Code Playgroud) 我有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) 我正在使用 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)
现在,我的搜索页面,其中有formDate和toDate它有与现场相比较DateTime在TranxLog。我尝试使用.withMatcher()但找不到比较日期的方法。
任何的想法?谢谢。
spring hibernate query-by-example hibernate-criteria spring-data-jpa
我仍在使用旧的org.hibernate.Criteria,并且对获取模式越来越困惑。在各种查询中,我需要以下所有变体,因此我无法通过注释来控制它。我只是将所有内容都切换到@ManyToOne(fetch=FetchType.LAZY),否则,查询中的任何内容都没有更改。
到目前为止我能找到的要么涉及 HQL 或 JPA2,要么只提供两种选择,但对于旧标准和(至少)以下三种情况,我需要它:
SELECT * FROM item JOIN order on item.order_id = order.idWHERE ...;SELECT item.* FROM item JOIN order on item.order_id = order.idWHERE ...; SELECT order.* FROM order WHERE ...;SELECT item.* FROM item JOIN order on item.order_id = order.idWHERE ...ORDER BY order.name, item.name;看起来没有明确指定fetch=FetchType.LAZY,一切都会像第一种情况一样急切地获取,这有时太糟糕了。我想,使用Criteria#setFetchMode,我可以获得第三种情况。我还没有尝试过,因为我仍然错过了第二个案例。我知道,它在某种程度上可能,还有的@BatchSize标注。
hibernate ×9
java ×4
criteria ×2
hql ×1
join ×1
jointable ×1
orm ×1
performance ×1
spring ×1
spring-boot ×1
unit-testing ×1