【问题标题】:What is the proper way for fetching or ignoring lazy loaded objects using hibernate and spring使用休眠和弹簧获取或忽略延迟加载对象的正确方法是什么
【发布时间】:2017-08-18 12:26:25
【问题描述】:

我正在使用 spring MVC + hibernate + jackson。 春季版本:4.3.x 休眠版本:4.3.x 我想创建两个 API——一个也获取 BeanB 对象,一个不获取 BeanB 对象。我也在使用 fetchtype.lazy。

我有以下豆子:

@Entity
class BeanA
{

@Id
int id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "BeanB_id")
private BeanB beanB;


//getters and setters
}

@Entity
class BeanB
{

@Id
int i;

//getters and setters
}

在我的控制器中,我有两种方法:(删除服务层以使问题变小。在我的服务层类中,我有@Transactional)

@RequestMapping(value = "/beanA/{id}" , method=RequestMethod.GET)
    public ResponseEntity<BeanA> findDetailedBeanAById(@PathVariable("id") int id ) 
    {
        // to return beanA object with beanB
        BeanA beanA = beanADao.findDetailedBeanAById(id);       
        return new ResponseEntity<BeanA>(beanA, HttpStatus.OK);
    }

@RequestMapping(value = "/beanA/{id}" , method=RequestMethod.GET)
    public ResponseEntity<BeanA> findNonDetailedBeanAById(@PathVariable("id") int id ) 
    {
        // to return beanA object without beanB
        BeanA beanA = beanADao.findNonDetailedBeanAById(id);        
        return new ResponseEntity<BeanA>(beanA, HttpStatus.OK);
    }

在我的道

public BeanA findDetailedBeanAById(long id) {


        BeanA beanA = (BeanA) getSession().get(BeanA.class, id);
        Hibernate.initialize(beanA.getBeanB())
        return beanA;
    }

public BeanA findNonDetailedBeanAById(long id) {

    BeanA beanA = (BeanA) getSession().get(BeanA.class, id);        
    return beanA;
}

当我点击 findNonDetailedBeanAById 控制器方法时,我收到错误:

org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: could not initialize proxy - no Session

当我点击 findNonDetailedBeanAById 控制器方法时,出现以下错误:

org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)`

需要做哪些改变?

【问题讨论】:

    标签: spring hibernate jackson


    【解决方案1】:

    对于详细的 findBy 方法,您可以构建自定义查询并获取查询中的 beanB,例如 getSession().createQuery("SELECT a FROM beanA a LEFT JOIN FETCH a.beanB WHERE a.id == :id")

    对于懒惰的 findBy 方法,我认为您需要在控制器级别添加 @Transactional(readonly=true),因为您在使用被注释为事务的服务获取 beanA 之后尝试使用它。我认为它试图从数据库中获取 beanB,但休眠会话可能已经关闭。

    我无法尝试我的任何建议,因为我只是在打电话。

    【讨论】:

    • 如果我添加@transactional,它将从数据库中获取详细信息.. 但那是我不需要的。我想利用延迟加载
    • 我的理解是,只有在你访问代码中的字段 beanB 时,它才会从数据库中取出它,然后 hibernate 只会在它周围创建一个代理对象。
    • 您是否尝试添加 3.5 中引入的 fetch profile hibernate? docs.jboss.org/hibernate/core/3.5/reference/en/html/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-15
    • 1970-01-01
    • 2011-06-15
    • 1970-01-01
    相关资源
    最近更新 更多