我的公司拥有高度可配置的数据库搜索服务,对于以编程方式配置查询非常有用.Criteria API功能强大,但当我们的某个开发人员重构其中一个数据对象时,标准限制并不表示它们在我们运行单元测试之前就已被破坏,或者更糟糕的是,它们是在我们的生产环境中运行的.最近,由于这个问题,我们的重构项目在工作时间上意外地翻了一倍,项目规划存在差距,如果我们知道实际需要多长时间,我们可能会采取另一种方法.
我想使用Example API来解决这个问题.如果我们在实际POJO属性上指定"where"条件,Java编译器可以大声地指示我们的查询是不可靠的.但是,Example API中只有这么多功能,并且它在很多方面都有限制.以下面的例子为例
Product product = new Product();
product.setName("P%");
Example prdExample = Example.create(product);
prdExample.excludeProperty("price");
prdExample.enableLike();
prdExample.ignoreCase();
Run Code Online (Sandbox Code Playgroud)
在这里,正在查询属性"name"(其中名称如'P%'),如果我要删除或重命名字段"name",我们会立即知道.但物业"价格"怎么样?它被排除,因为Product对象有一些默认值,所以我们将"price"属性名称传递给排除过滤器.现在,如果"价格"被删除,这个查询将在语法上无效,直到运行时才会知道.瘸.
另一个问题 - 如果我们添加第二个where子句会怎么样:
product.setPromo("Discounts up to 10%");
Run Code Online (Sandbox Code Playgroud)
由于对enableLike()的调用,此示例将匹配促销文本"折扣高达10%",还有"折扣高达10,000,000美元"或其他任何匹配的内容.通常,Example对象的查询范围的修改(例如enableLike()或ignoreCase()并不总是适用于要检查的每个属性.
这是第三个也是主要的问题 - 其他特殊标准呢?使用标准示例框架无法使每个产品的价格超过10美元.没有办法通过促销,降序来订购结果.如果Product对象在某个Manufacturer上加入,则无法在相关的Manufacturer对象上添加标准.没有办法在制造商的标准上安全地指定FetchMode(尽管这通常是Criteria API的问题 - 无效的获取关系无声地失败,甚至更多的是定时炸弹)
对于上述所有示例,您需要返回Criteria API并使用属性的字符串表示来进行查询 - 再次消除了Example查询的最大好处.
Example API有哪些替代方案可以获得我们需要的那种编译时建议?
我正在写一个非常简单的查询,但由于某种原因我得到重复的值.
Criteria cr = session.createCriteria(ProcessInstance.class, "p")
.add(Restrictions.isNull("end"));
@Cleanup ScrollableResults sr = cr.scroll(ScrollMode.FORWARD_ONLY);
while (sr.next()) {
pi = (ProcessInstance) sr.get(0);
String id = pi.getId(); //Getting duplicate values
}
Run Code Online (Sandbox Code Playgroud)
在pi.getId()返回重复值.即:*9,9,10,10,11,11 etc*
但是,直接在mysql中运行此查询
SELECT * FROM JBPM_PROCESSINSTANCE J where J.END_ IS NULL
Run Code Online (Sandbox Code Playgroud)
不返回重复值.
谁能发现什么是错的?
我想利用 Criteria API 的独立于数据库的 HQL 和类型安全。但我没有实体类。
我可以直接使用 Criteria API 吗?
我试图通过另一个查询的结果缩小Hibernate Criteria查询的结果集.我知道如何用JPQL解决这个问题:
FROM DocPackage p WHERE
EXISTS (SELECT g
FROM ObjectGroup g JOIN g.items i, Person per
WHERE g=p.applicantGroup
AND i.objectClass = 'org.cp.model.common.Person'
AND i.objectId=per.id
AND lower(concat(per.firstName,' ',per.lastName)) like :applicant
)
Run Code Online (Sandbox Code Playgroud)
但我无法想象如何使用Criteria进行此类查询.有关如何使用Criteria实现此选择的任何想法?使用Hibernate 3.3.
UPD:试图解决这个问题我做了以下Criteria查询:
Criteria resultCriteriaQuery = this.hibernateSession.createCriteria(DocPackage.class, "pack");
DetachedCriteria personSubquery = DetachedCriteria.forClass(Person.class, "pers").
add(Restrictions.like("pers.loFstLstName", "%" + searchObject.getApplicant().toLowerCase() + "%")).
add(Restrictions.eqProperty("itm.objectId", "pers.id"));
DetachedCriteria applicantsSubquery = DetachedCriteria.forClass(ObjectGroup.class, "objGrp").
add(Restrictions.eqProperty("pack.applcantGroup", "objGrp")).
createAlias("objGrp.items", "itm").
add(Restrictions.eq("itm.objectClass", "org.cp.model.common.Person")).
add(Subqueries.exists(personSubquery));
resultCriteriaQuery.add(Subqueries.exists(applicantsSubquery));
Run Code Online (Sandbox Code Playgroud)
但它不起作用.我有一个NullPointerException上resultCriteriaQuery.list().这个查询出了什么问题?有任何想法吗?
我想在 Spring Data中使用Hibernate Transformation.
我有一个AgentRecord属性为的实体
@Entity
public class AgentRecord extends AbstractEntity<Long> {
@ManyToOne
private User processedBy;
private String description;
private RecordType recordType;
private AgentRecordStatus status;
}
Run Code Online (Sandbox Code Playgroud)
我遵循将所需属性设置为调用的不同DTO AgentRecordDTO并将其返回到Client-side(gwt)的做法.
public class AgentRecordDTO implements IsSerializable {
private long processedBy;
private String description;
private RecordType recordType;
private AgentRecordStatus status;
}
Run Code Online (Sandbox Code Playgroud)
而不是获取实体的所有属性,我想获取一些属性并将它们设置AgentRecordDTO为new AgentRecordDTO()我可以在hql中执行的属性,但是想要使用Spring Data Specification.

我的AgentRepository是
public interface AgentRecordRepository extends CrudRepository<AgentRecord, Long>, JpaSpecificationExecutor<AgentRecord> {
}
Run Code Online (Sandbox Code Playgroud)
public Page<AgentRecordDTO> getAgentRecords(final …Run Code Online (Sandbox Code Playgroud) 我需要根据一些不同的限制来检索项目,一种是代码为 234,另一种是计算出的数量小于 10,但我不确定如何将值传递给 sqlRestrictions 方法。
我正在使用 {alias} 但它传递 Item 而不是 city 给这个。
List<Store> stores = (List<Store>) sessionFactory.getCurrentSession()
.createCriteria(Item.class)
.createAlias("Address", "address")
.createAlias("address.myJoinTable.city", "city")
.setProjection(pl)
.add(Restrictions.eq("address.myJoinTable.city",
session.load(City.class, myId)))
.add(Restrictions
.sqlRestriction("SELECT (
{alias}.id * {alias}.code * "
+ mynumber1 + " * " + mynumber2 + ")
as number from city
HAVING number < 10")
.setResultTransformer(
new AliasToBeanResultTransformer(Store.class))
.list();
Run Code Online (Sandbox Code Playgroud) 我有以下2个班级(为这篇文章修剪)
public class ApplicationVO implements Serializable {
/**
*
*/
private static final long serialVersionUID = -3314933694797958587L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", unique = true, nullable = false)
private Integer id;
@OneToOne(fetch = FetchType.LAZY, mappedBy = "application")
@Cascade({ CascadeType.ALL })
@JsonIgnore
private ApplicationHomeScreenVO applicationHomeScreen;
...
...
...
}
public class ApplicationHomeScreenVO implements Serializable {
/**
*
*/
private static final long serialVersionUID = -9158898930601867545L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", unique = true, nullable = false)
@JsonProperty("id") …Run Code Online (Sandbox Code Playgroud) 我有三个实体.那些是:
@Entity
public class Organization {
@Id
private long id;
@Column
private String name;
}
Run Code Online (Sandbox Code Playgroud)
@Entity
public class Book {
@Id
private Long id;
@Column
private String name;
@ManyToOne
private Organization organization;
}
Run Code Online (Sandbox Code Playgroud)
@Entity
public class Account {
@Id
private Long id;
@Column
private String name;
@ManyToOne
private Book book;
}
Run Code Online (Sandbox Code Playgroud)
在这三个实体中,我想执行以下sql:
SELECT acc.name, acc.id
FROM account acc
JOIN book b on acc.book_id = b.id
JOIN organization org on b.organization_id = org.id
WHERE org.name = 'XYZ'
Run Code Online (Sandbox Code Playgroud)
在这种情况下,Account实体与Organization …
我在使用 hibernate 从 java 实体中的枚举更新 postgres 数据库中的枚举字段时遇到问题,导致标题中出现错误。
我的数据库看起来像这样
\dT fulfillment_status
List of data types
Schema | Name | Description
--------+--------------------+-------------
public | fulfillment_status |
(1 row)
Run Code Online (Sandbox Code Playgroud)
这设置特定列fulfillment_status的类型,即
Column | Type | Collation | Nullable | Default
----------------------------+--------------------------------+-----------+----------+--------------------------------------
fulfillment_status | fulfillment_status | | not null |
Run Code Online (Sandbox Code Playgroud)
java实体类的相关章节
@Entity
@Table(name = "payments", uniqueConstraints = { @UniqueConstraint(columnNames = {"id"})})
public class Payment {
private FulfillmentStatus fulfillmentStatus;
public enum FulfillmentStatus {
PENDING, FULFILLED, FAILED, ABORTED
}
@Enumerated(EnumType.STRING)
@Column(name = "fulfillment_status", nullable = false, columnDefinition …Run Code Online (Sandbox Code Playgroud) 我们有 HibernateMetadataBuilderContributor 如下所示。它适用于 Hibernate 5 或 Spring boot 2.7。但当我们迁移到 Hibernate 6 或 Spring boot 3 时就不起作用了。
public class HibernateMetadataBuilderContributor implements MetadataBuilderContributor {
public static final String STRING_AGG = "string_agg";
public static final String STRING_AGG_ORDER_BY = "string_agg_order_by";
public static final String STRING_AGG_DISTINCT = "string_agg_distinct";
@Override
public void contribute(final MetadataBuilder metadataBuilder) {
metadataBuilder.applySqlFunction(STRING_AGG, new SQLFunctionTemplate(StandardBasicTypes.STRING, "string_agg(?1, ?2)"));
metadataBuilder.applySqlFunction(STRING_AGG_ORDER_BY, new SQLFunctionTemplate(StandardBasicTypes.STRING, "string_agg(?1, ?2 order by ?3)"));
metadataBuilder.applySqlFunction(STRING_AGG_DISTINCT, new SQLFunctionTemplate(StandardBasicTypes.STRING, "string_agg(distinct ?1, ?2)"));
}
}
Run Code Online (Sandbox Code Playgroud)
在 Hibernate 6 中找不到 SQLFunctionTemplate,有什么替代方案吗?
hibernate hibernate-criteria spring-data spring-data-jpa spring-boot
hibernate ×9
java ×6
spring-data ×2
criteria ×1
criteria-api ×1
enums ×1
jbpm ×1
join ×1
mysql ×1
postgresql ×1
spring ×1
spring-boot ×1
sql ×1
upgrade ×1