You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hibernate OGM+MongoDB问题:二次查询失效及更新后非ID字段无法获取

Troubleshooting Hibernate OGM 5.2.0.Alpha1 + MongoDB 3.6 Issues

Hey there, let's break down and solve the two issues you're running into with Hibernate OGM and MongoDB:

Issue 1: Can't execute a second query based on the first query's result

Possible Causes

  • Lazy Loading & Session Closure: Your CurrencyMaster has a @OneToMany association with PurchaseOrder, which defaults to lazy loading. If your first query runs in a Session that gets closed before the second query, accessing the lazy-loaded setOfPurchaseOrder (or using the entity in a new query) will fail because the entity is now detached.
  • Detached Entity in New Session: If you're trying to use the entity retrieved from the first query in a new Session without reattaching it, Hibernate OGM won't recognize it as a managed entity, leading to errors when executing the second query.

Solutions

  1. Keep Entities in the Same Session: Ensure both queries run within the same Hibernate Session. For example:
    try (Session session = sessionFactory.openSession()) {
        // First query
        CurrencyMaster currency = session.find(CurrencyMaster.class, currencyId);
        // Second query using the result
        Query<PurchaseOrder> query = session.createQuery("FROM PurchaseOrder p WHERE p.currencyMaster = :currency", PurchaseOrder.class);
        query.setParameter("currency", currency);
        List<PurchaseOrder> orders = query.getResultList();
    }
    
  2. Eagerly Fetch Associations: If you need to use the entity outside the initial Session, modify your first query to fetch the association upfront with JOIN FETCH:
    Query<CurrencyMaster> query = session.createQuery("SELECT c FROM CurrencyMaster c JOIN FETCH c.setOfPurchaseOrder WHERE c.id = :id", CurrencyMaster.class);
    query.setParameter("id", currencyId);
    CurrencyMaster currency = query.getSingleResult();
    
  3. Reattach Detached Entities: If you must use a new Session, reattach the entity with session.merge() before running the second query:
    try (Session session1 = sessionFactory.openSession()) {
        currency = session1.find(CurrencyMaster.class, currencyId);
    }
    try (Session session2 = sessionFactory.openSession()) {
        CurrencyMaster managedCurrency = session2.merge(currency);
        // Now run the second query with managedCurrency
    }
    

Issue 2: Can't get fields other than ID after update operation

Possible Causes

  • Detached Entity After Update: After performing an update, if you're working with a detached entity instance, Hibernate won't automatically refresh its state from the database.
  • Missing Session Refresh: The update operation might modify the database, but the in-memory entity object isn't synced unless you explicitly refresh it.
  • Transaction Boundary Issues: If the update isn't committed within a transaction, the changes might not be persisted to MongoDB, leading to stale data when you retrieve the entity.

Solutions

  1. Refresh the Entity After Update: After executing the update, call session.refresh(entity) to reload its state from the database:
    try (Session session = sessionFactory.openSession()) {
        Transaction tx = session.beginTransaction();
        CurrencyMaster currency = session.find(CurrencyMaster.class, currencyId);
        currency.setCode("USD"); // Update field
        session.update(currency);
        tx.commit();
        session.refresh(currency); // Now all fields will be up-to-date
    }
    
  2. Use merge() to Get Updated Entity: Instead of update(), use session.merge() which returns the managed, updated entity:
    try (Session session = sessionFactory.openSession()) {
        Transaction tx = session.beginTransaction();
        CurrencyMaster detachedCurrency = ...; // Your detached entity with updates
        CurrencyMaster updatedCurrency = session.merge(detachedCurrency);
        tx.commit();
        // updatedCurrency has all the latest fields from the database
    }
    
  3. Ensure Transactions Are Committed: Always wrap update operations in a transaction and commit it before accessing the entity. Without a committed transaction, MongoDB might not persist the changes immediately.

Your Entity Class Reference

Here's the formatted version of your provided entity code for reference:

@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;
    
    // Getters and Setters
}

@Entity
@Table(name = "...") // Your PurchaseOrder table name
public class PurchaseOrder {
    // Your PurchaseOrder fields, including @ManyToOne to CurrencyMaster
    @ManyToOne
    private CurrencyMaster currencyMaster;
    
    // Other fields, getters and setters
}

内容的提问来源于stack exchange,提问作者vishvas4u

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:36:52