バックグラウンド
データベースと対話してHibernateを介していくつかのCRUD操作を実行するApache-CXFを使用してRESTfulWebサービスを実装しようとしています。Webサービスは、JacksonJAX-RSプロバイダーを使用してJSON形式のオブジェクトを消費および生成します。
現在、応答オブジェクトをシリアル化しようとすると、Jacksonプロバイダーからバブリングする「コレクションの遅延初期化に失敗しました...セッションまたはセッションが閉じられていません」という例外が発生しています。
サービスメソッドに@Transactional
そのマークを付けた場合、応答をシリアル化したときにジャクソンプロバイダーがセッションを利用できると想定しましたが、そうではないようです。
質問
シリアル化中にJacksonがオブジェクトを歩いているときに、休止状態のセッションを利用できるようにするにはどうすればよいですか?
私が試したこと
スプリング構成
<context:component-scan base-package="com.db.cif.mapper" />
<context:component-scan base-package="com.db.cif.mapper.repository" />
<context:annotation-config />
<tx:jta-transaction-manager>
<property name="entityManagerFactory" ref="entityManagerFactory" />
</tx:jta-transaction-manager>
<tx:annotation-driven />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="cifmapper" />
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
</property>
</bean>
<!-- JAX-RS Configuration -->
<jaxrs:server id="mappingService" address="/">
<jaxrs:serviceBeans>
<ref bean="mappingServiceBean" />
</jaxrs:serviceBeans>
<jaxrs:extensionMappings>
<entry key="json" value="application/json" />
</jaxrs:extensionMappings>
<jaxrs:providers>
<ref bean="jsonProvider" />
</jaxrs:providers>
</jaxrs:server>
<bean id="mappingServiceBean" class="com.db.cif.mapper.MappingService" />
<bean id="jsonProvider" class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" />
サービスビーン
@Service("mappingService")
@Transactional
public class MappingService
{
private static final Logger logger = Logger.getLogger(MappingService.class);
@Autowired
@Qualifier("mappingRepository")
private MappingRepository mappingRepository;
@GET
@Path("/collections/{id}")
@Produces(MediaType.APPLICATION_JSON)
public Collection getCollection(@PathParam("id") String id)
{
if(logger.isDebugEnabled())
{
logger.debug(String.format("Invoked getCollection, Collection id: %s", id));
}
return this.mappingRepository.getCollection(id);
}
@POST
@Path("/collections/")
@Consumes(MediaType.APPLICATION_JSON)
public Response addCollection(Collection collection)
{
if(logger.isDebugEnabled())
{
logger.debug(String.format("Invoked addCollection, Collection: %s", collection));
}
this.mappingRepository.createCollection(collection);
return Response.ok(collection).build();
}
}
コレクションBean
@Entity
@Table(schema = "CIFMAPPER", name = "COLLECTION")
public class Collection implements Serializable
{
private static final long serialVersionUID = 1579878442412232635L;
@Id
@Column(name = "ID")
private String id;
@Column(name = "SRC_ENDPT_ID", nullable = false, insertable = false, updatable = false)
private long sourceEndpointId;
@Column(name = "DEST_ENDPT_ID", nullable = false, insertable = false, updatable = false)
private long destinationEndpointId;
@Column(name = "DESCRIPTION")
private String description;
@Column(name = "START_DATE", nullable = false)
private Date startDate;
@Column(name = "END_DATE")
private Date endDate;
@ManyToOne(optional = false)
@JoinColumn(name = "SRC_ENDPT_ID")
private Endpoint source;
@ManyToOne(optional = false)
@JoinColumn(name = "DEST_ENDPT_ID")
private Endpoint destination;
@OneToMany(mappedBy = "collection", targetEntity = MappingGroup.class, fetch = FetchType.EAGER)
private List<MappingGroup> mappingGroups;
//Getters and Setters Removed For Brevity
}