![](/img/trans.png)
[英]Hibernate Ogm 2nd query based on 1st query result and also can't get mapped object fields(other than id) after update
[英]Hibernate OGM with Mongodb Result of 2nd Query on same table dependent on Result fields of 1st query of same table
我在Mongodb(3.4)中使用Hibernate OGM(5.2.0.Alpha1)
@Entity
@Table(name = "service")
@JsonInclude(Include.NON_EMPTY)
public class Service {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "SERVICE_ID", unique = true, nullable = false)
@JsonSerialize(using = ToStringSerializer.class)
public ObjectId id;
private String name;
@ManyToOne
@JsonIgnore
public Lab lab;
getter....
setter....
}
@Entity
@Table(name = "lab")
@JsonInclude(Include.NON_EMPTY)
// @JsonFilter(value=SalesUtils.MY_CUSTOM_FILTER_FOR_LAB)
public class Lab {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@JsonSerialize(using = ToStringSerializer.class)
@Column(name = "LAB_ID", unique = true, nullable = false)
public ObjectId id;
private String name;
@OneToMany(mappedBy = "lab")
public List<Service> listOfServices;
getter....
setter....
}
道层:
public <T> List<T> executeQuery(String query, Integer startPosition, Integer noOfRecords, T t) {
List<T> listOfT = new ArrayList<>();
if (SalesUtils.isObjectisNullOrEmpty(startPosition, noOfRecords)) {
listOfT = entityManager.createNativeQuery(query.toString(), t.getClass()).getResultList();
} else {
listOfT = entityManager.createNativeQuery(query.toString(), t.getClass()).setFirstResult(startPosition)
.setMaxResults(noOfRecords).getResultList();
}
return SalesUtils.isListIsNullOrEmpty(listOfT) ? new ArrayList<>() : listOfT;
}
服务层:(问题:实验室名称:空)
@Transaction
public void executeQuery(){
String query = "db.service.find({} , {"name":1})";
List<Service> listOfServices = myDao.executeQuery(query , null , null ,new Service());
String anotherQuery = " { $query : { name : "CDG Service"}}";
List<Service> listOfAnotherServices = myDao.executeQuery(query , null , null ,new Service());
if (!SalesUtils.isListIsNullOrEmpty(listOfAnotherServices )) {
System.out.println(listOfAnotherServices.get(0).getName());
System.out.println(listOfAnotherServices.get(0).getLab().getName()); //null
}
}
服务层:(临时解决方案)
@Transaction
public void executeQuery(){
//Temporary solution : added lab_LAB_ID field in below 1st query
String query = "db.service.find({} , {"name":1,"lab_LAB_ID":1})";
List<Service> listOfServices = myDao.executeQuery(query , null , null ,new Service());
String anotherQuery = " { $query : { name : "CDG Service"}}";
List<Service> listOfAnotherServices = myDao.executeQuery(query , null , null ,new Service());
if (!SalesUtils.isListIsNullOrEmpty(listOfAnotherServices )) {
System.out.println(listOfAnotherServices.get(0).getName());
System.out.println(listOfAnotherServices.get(0).getLab().getName()); //not null
}
}
详细说明:
在这里,我仅使用第一个查询执行(变量名=查询)然后执行第二个查询(变量名= anotherQuery)来获取服务表的“名称”字段,但无法获取实验室对象。
所以我使用第一个查询执行(变量名=查询)获得了“名称”和“ lab_LAB_ID”两个字段,然后又执行了第二个查询(变量名= anotherQuery),所以我不能成功地获得实验室对象。
我不明白 即使查询不同并且变量名称也不同,第二查询结果似乎也取决于第一查询结果字段。
我说的对吗
编辑:问题是第一个查询的结果被缓存(在会话级别),然后在第二个查询中重用。 因为您运行的初始查询不会返回所有字段,所以实体仅被部分初始化。 当您要重新创建实体时,请确保返回所有字段。 当用户尝试重新创建仅包含属性子集的实体时,Hibernate OGM应该引发异常。 我将为此创建一个新的JIRA。
当指定{name: 1}
,您只要求返回以下字段: _id
和name
; 因为您要求提供服务,所以Hibernate OGM会将这些值转换为Service类。 问题在于结果不包含实验室,因此该字段为空(应该有一个例外)。
当您运行db.service.find({} , {"name":1,"lab_LAB_ID":1})
,您还将返回Lab标识符,OGM还将通过此附加信息将实验室添加到服务。
如果需要整个服务,则应使用本机查询:
String query = "db.service.find({})";
但我建议针对这种情况进行HQL查询:
String hqlQuery = "FROM Service";
List<Service> services = entityManager.createQuery(hqlQuery, Service.class)
.getResultList();
顺便说一句,您不必每次运行查询时都创建一个新的Service(),您可以将参数定义为Class<T>
,然后传递Service.class
。
使用本机查询时,如果您选择在根类上应用投影,则必须删除toEntity,因为不允许部分提取实体。 可能会在该产品的下一版本中引入异常抛出,以防止这种使用。 这也是H2方言上Hibernate ORM(5.2 | 5.3)的当前行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.