2017-08-18 18 views
0

我正在使用spring MVC + hibernate + jackson。 Spring版本: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控制器满足HOD,我得到的错误为:

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

需要什么样的变化做?

回答

0

因为你可以建立一个自定义查询和获取的beanB查询里面的详细findBy方法,像getSession().createQuery("SELECT a FROM beanA a LEFT JOIN FETCH a.beanB WHERE a.id == :id")

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

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

+0

如果我添加@transactional,它会从数据库中获取细节..但这是我不需要的。我想利用延迟加载 – shubh

+0

我的理解是,只有在代码中访问字段beanB之后,它才会将其从数据库中提取出来,然后hibernate才会创建一个代理对象。 – vampYr09

+0

您是否尝试添加3.5中引入的fetch配置文件hibernate? http://docs.jboss.org/hibernate/core/3.5/reference/en/html/performance.html#performance-fetching-profiles – vampYr09