我正在开发一个 Java 项目,使用 Hibernate 来管理 SQL 数据库上的数据。我尝试从数据库中获取实例列表,这些实例具有它们共享的组的最小时间戳。该组由容器建模。
这是一个最小的模型草图:
@Entity
@Table(name = "object")
public class Object implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.Auto)
long obj_id;
@Column(name = "time_stamp", nullable = false)
Date timestamp;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "container_id", nullable = false)
Container con;
}
@Entity
@Table(name = "container")
public class Container{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
long con_id;
@OneToMany(mappedBy = "container")
List<object> obj_list;
}
所以有一些带有时间戳的对象和对这些对象进行分组的容器。
例如,有两个容器,con_a 和 con_b:
Container con_a:
con_id = 1
obj_list = {obj_a, obj_b}
Container con_b:
con_id = 2
obj_list = {obj_c}
以及三个对象,obj_a、obj_b、obj_c:
Object obj_a
obj_id = 1
timestamp = 10
con = con_a
Object obj_b
obj_id = 2
timestamp = 20
con = con_a
Object obj_c
obj_id = 3
timestamp = 30
con = con_b
此示例中所需的列表如下所示:
List<Object> = {obj_a, obj_c}
我似乎在转圈,因为我什至不知道从哪里“开始”查询:
Criteria crit = session.createCriteria(Container.class). ...
或者
Criteria crit = session.createCriteria(Object.class). ...
这对我来说似乎都是可能的,但我只是不知道如何从这两种可能性中继续下去。
更新 [2014.07.11, 14:19]:
我尝试使用 Object 类开始查询并使用了子查询:
Session session = getSession();
Transaction transaction = session.beginTransaction();
DetachedCriteria IdListOfGroupMinimum = DetachedCriteria.forClass(Object.class, "obj")
IdListOfGroupMinimum.createAlias("con.id", "containerId")
.setProjection(
.Projections.projectionList()
.add(Projections.property("obj.id"))
.add(Projections.min("obj.timestamp"))
.add(Projections.groupProperty("containerId")))
.setProjection(Projection.property("obj.id"));
Criteria objects = session.createCriteria(object.class, "obj")
objects.add(Subqueries.in("obj.id", IdListOfGroupMinimum));
List<Object> = objects.list();
但我收到以下错误:
javax.servlet.ServletException:org.hibernate.QueryException:不是关联:id
我试图这样做:
SELECT * from Object
WHERE id IN (
SELECT obj.id
FROM Object obj
INNER JOIN (
SELECT obj.containerID, MIN(obj.timestamp) AS minimum
FROM Object obj
GROUP BY obj.containerID) subquery
ON obj.containerID = subquery.containerID
WHERE obj.timestamp = subquery.minimum
)