2015-12-28 34 views
1

我一直在使用Spring MVC + Hibernate + MySQL构建的RESTful服务。具有双向关系的Spring MVC +休眠

在数据库中,我有两个表格 - 主题和评论。主题表的ID列是注释表的外键。我生成使用Hibernate工具模型和DAO:

主题模型:

... 

@OneToMany(fetch = FetchType.LAZY, mappedBy = "topic") 
public Set<Comment> getComments() { 
    return this.comments; 
} 

... 

评价模型:

... 

@ManyToOne(fetch = FetchType.LAZY) 
@JoinColumn(name = "topic_id", nullable = false) 
public Topic getTopic() { 
    return this.topic; 
} 

... 

这里谈到的问题。我可以使用findById()获取分离的主题对象DT。但是,每次我想发送DT作为前端的响应主体时,就会抛出'无会话'异常,因为LAZY对象 - 注释只能在会话中访问。

1)如果我不改变EAGER,我的解决方案是从DT创建新Topic对象NT和检索值(除注释)。然后返回NT作为响应主体。这是最佳做法吗?

2)如果我将@OneToMany部分更改为EAGER,问题仍未解决。因为当我发送DT时,包含了一组评论,每个评论与@ManyToOne声明的主题有关系。所以仍然没有引发任何会话异常。 3)如果我将@OneToMany@ManyToOne更改为EAGER,计算机将停留,因为它将从主题到评论并返回到主题,迭代地,永不停止。

那么,你们如何建议返回主题作为响应主体。

+1

创建视图对象或DTO(数据传输对象),以信息返回给前端是不寻常或不好的做法。您可以通过将主题的注释设置为空或重新初始化为空数组来摆脱“无会话”。我不确定您需要注释模型中的ManyToOne双向关系注释。事实上,你有一个主题的评论列表,并在那里注释它应该是足够的。 –

+0

Checkout [jackson-datatype-hibernate](https://github.com/FasterXML/jackson-datatype-hibernate)可用于延迟加载方面 – nickmesi

+0

有关处理循环对象图的信息,请参见[JsonIdentityInfo](http:// wiki。 fasterxml.com/JacksonFeatureObjectIdentity) – nickmesi

回答

0

经过长时间的研究,我终于有了可以接受的解决方案。

但首先,使用双向关系的原因可以找到here

我的解决方案是使用jackson-datatype-hibernate,这要归功于@ZeeMesi。这里的步骤:

步骤1:依赖

<dependency> 
     <groupId>com.fasterxml.jackson.datatype</groupId> 
     <artifactId>jackson-datatype-hibernate4</artifactId> 
     <version>2.6.4</version> 
    </dependency> 

步骤2:弹簧上下文

<mvc:annotation-driven> 
    <mvc:message-converters> 
     <!-- Use the HibernateAware mapper instead of the default --> 
     <beans:bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> 
      <beans:property name="objectMapper"> 
       <beans:bean class="com.hersbitcloud.cancercloud.HibernateAwareObjectMapper" /> 
      </beans:property> 
     </beans:bean> 
    </mvc:message-converters> 
</mvc:annotation-driven> 

步骤3:创建新的类

公共类HibernateAwareObjectMapper延伸ObjectMapper {

public HibernateAwareObjectMapper() { 
    Hibernate4Module hm = new Hibernate4Module(); 
    registerModule(hm); 
} 

然后,所有懒洋洋地提取的对象将是null