简体   繁体   English

基于第一查询结果的Hibernate Ogm第二查询,更新后也无法获取映射的对象字段(除id外)

[英]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, 在服务层中

  1. first i executed query to get "id,code,total" from purchase order and successfully got all the fields. 首先,我执行查询以从采购订单中获取“ id,代码,总计”,并成功获取所有字段。

  2. then i updated purchase order. 然后我更新了采购订单。

  3. 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.

相关问题 使用Mongodb在同一表上进行第二次查询的结果的Hibernate OGM,取决于同一表的第一项查询的结果字段 - Hibernate OGM with Mongodb Result of 2nd Query on same table dependent on Result fields of 1st query of same table Hibernate Critieria在条件上将两个表连接到第二个表上,并在第一个表上产生结果 - Hibernate Critieria join two tables with condition on 2nd table and result the 1st table Hibernate OGM聚合查询结果 - Hibernate OGM result of aggregation query Hibernate OGM聚合查询结果字段不适用于包装器类型 - Hibernate OGM Aggregate Query result fields not working with Wrapper Types 检查第一时间选择器是否早于第二时间选择器 - Check if 1st timepicker earlier than 2nd timepicker 如何使用第一个JSON对象覆盖第二个对象JSON - How to override the 2nd Object JSON with 1st JSON object 从第一个活动拨打电话后,第二个活动没有通话 - 2nd Activity doesn't call after calling from 1st Activity 在comboBox中显示对象的第一个和第二个值 - show the 1st and 2nd value of object in comboBox 如果我将提供第一栏的文字,我该如何获取第二栏的文字 - How can i get text of 2nd column if i will provide the text of 1st column 我如何获得从第一帧文本字段输入文本到第二帧文本的输出 - How I can get output from 1st frame textfield input text to 2nd frame textArea
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM