我正在尝试使用Hibernate进行复杂的查询。我一直倾向于“标准”,但是我开始怀疑这是不可能的,因此任何建议都将有所帮助。
我有一个如下的实体结构:
public class Attribute {
private Integer id;
private String name;
private Set<Value> values;
}
public class Instance {
private Integer id;
private int instanceRef;
private Set<Value> values;
}
public class Value {
private Integer id;
private Attribute attribute;
private String localAttributeName;
private Instance instance;
private String value;
}
这些实体与您期望的相关:
value.attribute_id --> attribute.id
value.instance_id --> instance.id
现在,我希望能够采用一组属性/值对(字符串)并找到包含 所有
属性/值对的所有实例。在“值”中,只有attribute和localAttributeName中的一个为非空值,因此属性名称可以与localAttributeName或attribute.name匹配。最后使事情复杂化的是,值的唯一索引位于(html" target="_blank">实例,属性,值)或(实例,localAttributeName,值)上,也就是说,在实例中,任何给定的属性都可以具有多个值。
这是我到目前为止的内容:
public List<Instance> getMatchingInstances(Map<String, String> attrValues) {
Criteria crit = session.createCriteria(Instance.class, "i");
for(Map.Entry<String, String> entry : attrValues) {
DetachedCriteria valueCrit = DetachedCriteria.forClass(Value.class, "v");
// Do something here with valueCrit
crit.add(Subqueries.exists(valueCrit));
}
return crit.list();
}
根据我所做的研究,我为“做某事”部分所做的尝试是:
// This would only check localAttributeName and not attribute.name.
// That's okay -- once I get the rest to work, I can figure this out.
valueCrit.add(Restrictions.eq("localAttributeName", entry.getKey());
valueCrit.add(Restrictions.eq("value", entry.getValue());
valueCrit.add(Restrictions.eqProperty("v.instance_id", "i.id"));
但这在下面抛出了一个异常,我怀疑这是在告诉我我无法使用Criteria来做到这一点,但是我很乐意学习其他情况:
java.lang.NullPointerException
at org.hibernate.loader.criteria.CriteriaQueryTranslator.getProjectedTypes(CriteriaQueryTranslator.java:341)
这样做的最佳方法是什么?
经过数小时的努力,我找到了解决方案。希望这对其他人有用。为了使此可行,我需要解决三个主要问题:
我在下面的代码中强调了其中的每一个。
首先,要摆脱异常,我发现子查询需要一个投影,下面突出显示。我只是对Instance的“ id”属性进行了投影。
其次,为了获得连接,我使用了Criteria.createCriteria()方法创建了一个左外部连接。因为在联接的不同级别上有多个条件,所以我必须保存联接的条件并将表达式分别附加到它们上。这让我在子查询中执行OR表达式。
最后,我必须添加一个eqProperty()子句以将子查询映射回主条件。就像它需要在结果SQL中一样,我使用了:instance.id=i.id。因为我已经将实例标准映射到“i”,并将此子句添加到“值标准”中,所以这被转换为SQL:v.instance_id =i.id。
这是工作代码:
public List<Instance> getMatchingInstances(Map<String, String> attrValues) {
Criteria crit = session.createCriteria(Instance.class, "i");
for(Map.Entry<String, String> entry : attrValues) {
String attrName = entry.getKey();
String val = entry.getValue();
// Create the subquery
DetachedCriteria valueCrit = DetachedCriteria.forClass(Value.class, "v");
// Join the Attribute object (left outer join)
DetachedCriteria attrCrit =
valueCrit.createCriteria("attribute", CriteriaSpecification.LEFT_JOIN);
// Put together the OR statement on the Attribute joined criterion.
Criterion localAttr = Restrictions.eq("v.localAttributeName", attrName);
Criterion globalAttr = Restrictions.eq("name", attrName);
attrCrit.add(Restrictions.or(localAttr, globalAttr));
// Simple column equality on the subquery criterion.
valueCrit.add(Restrictions.eq("value", val));
// Map the subquery back to the outer query.
valueCrit.add(Restrictions.eqProperty("instance.id", "i.id"));
// Add the missing projection.
valueCrit.setProjection(Projections.property("id"));
// Add this subquery to the outer query.
crit.add(Subqueries.exists(valueCrit));
}
return crit.list();
}
问题内容: 我有以下实体 以下是我的行动 我想获取具有特定操作集的规则列表,我正在尝试执行此操作 但是获取org.hibernate.MappingException:集合不是一个关联:异常。 编辑 因此,在jbrookover的指导下,我尝试为Action命名为RuleAction的包装器类,并能够建立一个oneToMany关系,此外,我还如下修改了查询 但是,这将返回所有具有EMAIL或POS
这定义了几个接收器、指标等。但它们是收集的吗? 假设我将 添加到 文件中,并启用了所有实例指标(主实例、应用程序、工作线程、执行程序、驱动程序、随机排序服务、应用程序主站)。 假设设置了 jmx 端口。 在哪里收集指标:我应该连接到所有群集节点还是仅连接到驱动程序节点?
问题内容: 我想在Linux / AMD64 / Debian和GCC 4.6上开发一个多线程C 应用程序(最终大多数C 代码将由应用程序本身生成,可以将其视为高级领域特定语言)。可能是最新的C ++ 11标准)。 我真的想对我的所有堆分配使用Boehm的保守垃圾收集器,因为我想分配而不用担心。我假设Boehm的GC运行良好。 使用(而不是C)C 的主要动机是所有的算法和集合 … 由C 标准库提供
我的Ionic 5应用程序中有以下Firestore数据库结构。 书(集合) {bookID}(带有book字段的文档) 赞(子集合) {userID}(文档名称作为带有字段的用户ID) 集合中有文档,每个文档都有一个子集合。Like collection的文档名是喜欢这本书的用户ID。 我正在尝试进行查询以获取最新的,同时尝试从子集合中获取文档以检查我是否喜欢它。 我在这里做的是用每个图书ID调
我有两张桌子, 这两个表之间的关系是CustomerNumber 我的客户地图 以及账户映射 函数i DAO QueryHelper。getCustomerCriteria 现在我只想搜索有银行账户的客户。我想在Hibernate中设置一个条件。但我就是不知道怎么做? 搜索时,您可以输入客户编号、客户名称、电话号码和/或城市,并选择要显示多少结果。 首先,我想我可以编写一个命名查询,但之后你就有了
我想获取地图的值,找到min值,并为地图的每个条目构造一个新的CodesWitMinValue实例。我希望使用Java11个流,我可以在多行中使用多个流(一个用于min值,一个用于转换)来实现这一点。是否可以使用java 11流和收集器在单行中实现?谢谢。