简体   繁体   中英

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)

@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:

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

In Service Layer,

  1. first i executed query to get "id,code,total" from purchase order and successfully got all the fields.

  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.

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.

Or, even better, why don't you try using a JPQL query?

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM