[英]Hibernate Ogm 2nd query based on 1st query result and also can't get mapped object fields(other than id) after update
i am using Hibernate OGM (5.2.0.Alpha1) with Mongodb (3.6) 我在Mongodb(3.6)中使用Hibernate OGM(5.2.0.Alpha1)
@Entity
@Table(name = "currency_master)
@JsonInclude(Include.NON_EMPTY)
public class CurrencyMaster{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@JsonSerialize(using = ToStringSerializer.class)
@Column(name = "CURRENCY_ID", unique = true, nullable = false)
private ObjectId id;
private String code;
@OneToMany(mappedBy = "currencyMaster")
private Set<PurchaseOrder> setOfPurchaseOrder;
getter()
setter()
}
@Entity
@Table(name = "purchase_order)
@JsonInclude(Include.NON_EMPTY)
public class PurchaseOrder {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@JsonSerialize(using = ToStringSerializer.class)
@Column(name = "PURCHASE_ORDER_ID", unique = true, nullable = false)
private ObjectId id;
private String purchaseOrderNo;
private Double total;
@ManyToOne
@JsonIgnore
private CurrencyMaster currencyMaster;
getter()
setter()
}
DAO Layer: DAO层:
@SuppressWarnings("unchecked")
@Override
public <T> void update(T t) {
try {
Field[] fields = t.getClass().getDeclaredFields();
Map<String, Object> mapUpdatedFields = new HashMap<String, Object>();
for (Field field : fields) {
field.setAccessible(true);
mapUpdatedFields.put(field.getName(), field.get(t));
}
T newT = this.getById(mapUpdatedFields.get("id").toString(), t);
mapUpdatedFields.remove("id");
mapUpdatedFields.forEach((k, v) -> {
if (!AccountingMethodUtils.isObjectisNullOrEmpty("update()", v)) {
AccountingMethodUtils.setValueToField(newT, k, v);
}
});
entityManager.merge(newT);
} catch (Exception e) {
e.printStackTrace();
LOGGER.error(
"update() of DAO : (Error in outer try..catch) Error in updating record of {} and Error is {}.",
t.getClass(), e);
}
}
@Override
public <T> List<T> executeQuery(String query, Integer startPosition, Integer noOfRecords, T t) {
List<T> listOfT = new ArrayList<>();
if (AccountingMethodUtils.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 AccountingMethodUtils.isListIsNullOrEmpty(listOfT) ? new ArrayList<>() : listOfT;
}
Service Layer: 服务层:
@Override
@Transactional
public String updatePurchaseOrder(AccountingRequestBody input) {
PurchaseOrder purchaseOrder = AccountingMethodUtils.getObjectMapper().convertValue(input.getJsonOfObject(),
PurchaseOrder.class);
// Query : db.purchase_order.find( {'_id' : ObjectId("5ab88323191bb91e78f9e33d") } , { 'purchaseOrderNo' : 1, 'currencyMaster_CURRENCY_ID' : 1 , 'total' : 1 })
StringBuilder sb = new StringBuilder().append("db.").append(AccountingVariableUtils.TABLE_NAME_FOR_PURCHASE_ORDER)
.append(".find( {'_id' : ObjectId('" + purchaseOrder.getId().toString()
+ "') } , { 'purchaseOrderNo' : 1, 'currencyMaster_CURRENCY_ID' : 1 , 'total' : 1 })");
List<PurchaseOrder> poFromDB = purchaseOrderDao.executeQuery(sb.toString(), null, null, new PurchaseOrder());
if (!AccountingMethodUtils.isListIsNullOrEmpty(poFromDB)) {
System.out.println("id before update : " + poFromDB.get(0).getCurrencyMaster().getId()); // Output: 5ab8830b191bb91e78f9e221
System.out.println("code before update : " + poFromDB.get(0).getCurrencyMaster().getCode()); // Output: INR
}
purchaseOrderDao.update(purchaseOrder);
poFromDB = purchaseOrderDao.executeQuery(sb.toString(), null, null, new PurchaseOrder());
if (!AccountingMethodUtils.isListIsNullOrEmpty(poFromDB)) {
System.out.println("id after update : " + poFromDB.get(0).getCurrencyMaster().getId()); // Output: 5ab8830b191bb91e78f9e221
System.out.println("code after update : " + poFromDB.get(0).getCurrencyMaster().getCode()); // Output: null //?????????????????????
}
}
output: 输出:
id before update : 5ab8830b191bb91e78f9e221
code before update: INR
id after update : 5ab8830b191bb91e78f9e221
code afterupdate: null ?????????????????????
Description: 描述:
Currency Master has one to many mapping(bidirectional) with purchase order. Currency Master具有与采购订单的一对多映射(双向)。
In Service Layer, 在服务层中
first i executed query to get "id,code,total" from purchase order and successfully got all the fields. 首先,我执行查询以从采购订单中获取“ id,代码,总计”,并成功获取所有字段。
then i updated purchase order. 然后我更新了采购订单。
then i again executed same query ( to get "id,code,total" from purchase order) after update then i can get id of currency master but can't get code of currency master. 然后我在更新后再次执行相同的查询(从采购订单中获取“ id,代码,总计”),然后我可以获取货币主的ID,但无法获取货币主的代码。
Is Am i Right??? 我说得对吗???
I think the problem is that you are using projection in your native query and trying to create the entity without retrieving all the information needed. 我认为问题在于您正在本机查询中使用投影,并试图在不检索所有所需信息的情况下创建实体。 I would remove the projection part from the native query and only use:
我将从本地查询中删除投影部分,仅使用:
db.purchase_order.find( {'_id' : ObjectId("5ab88323191bb91e78f9e33d") } );
This happens because Hibernate OGM caches results, so you have to make sure to initialize entities correctly. 发生这种情况是因为Hibernate OGM缓存了结果,因此您必须确保正确初始化实体。
Or, even better, why don't you try using a JPQL query? 或者,甚至更好的是,为什么不尝试使用JPQL查询呢?
PurchaseOrder order = em.createQuery( "FROM PurchaseOrder po WHERE po.id = :id", PurchaseOrder.class )
.setParameter( "id", "5ab88323191bb91e78f9e33d" )
.getSingleResult();
By the way, Hibernate OGM shouldn't let you do this kind of things and will throw an exception in follow-up versions. 顺便说一句,Hibernate OGM不应让您执行此类操作,并且会在后续版本中引发异常。
Last, I would recommend to update to Hibernate OGM 5.3.0.Final or at least to 5.2.0.Final (if there is any reason for you to stick to stick to the 5.2 family). 最后,我建议更新到Hibernate OGM 5.3.0.Final或至少更新到5.2.0.Final(如果有任何理由要坚持使用5.2系列)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.