当服务在自动发现包中时,无法保持具有tynamo-resteasy的实体

时间:2013-01-20 19:27:28

标签: hibernate jpa resteasy tapestry tynamo

在我发现tynamo和resteasy集成时,我面临着保存数据的问题,我部分解决了(因此我将部分分享它;))。 用户指南在此处:http://docs.codehaus.org/display/TYNAMO/tapestry-resteasy+guide

我写了一个休息服务,允许"用户"在我的系统用户中注册:

package com.myorg.mobile.pushup.rest;
//[...]

/**
 * bla blah obfuscated pretty comments.
 * 
 * @author jrrevy
 * 
 */
@Path("/user")
public class UserResource {

    private Session session;

    /**
     * Constructeur du service
     * 
     * @param session
     *            Hibernate session
     */
    public UserResource(Session session) {
        this.session = session;
    }   

    /**
     * Lecture de tous les utilisateurs
     * 
     * @return une liste des utilisateurs existants
     */
    @GET
    @Produces("application/json")
    public List<User> getAllDomains() {
        return session.createCriteria(User.class).list();
    }

    /**
     * Create User.
     * 
     * @param user
     *            user to create
     * @return a Web Response
     */
    @POST
    @PUT
    @Produces({ "application/xml", "application/json" })
    public Response createOrUpdate(User user) {
        session.saveOrUpdate(user);
        return Response.ok().build();
    }

访问数据库运行良好(我让我的用户回来了,看到INSERT INTO命令进入日志),但这项服务永远不会持久。似乎交易从未被提交。

我正在使用0.3.0版本的tapestry-model-hibernate和tapestry-resteasy:

<dependencies>

    <dependency>
        <groupId>org.tynamo</groupId>
        <artifactId>tapestry-model-hibernate</artifactId>
        <version>0.3.0</version>
    </dependency>


    <dependency>
        <groupId>org.tynamo</groupId>
        <artifactId>tapestry-resteasy</artifactId>
        <version>0.3.0</version>
    </dependency>

</dependencies>

请参阅上面的答案,但如果您找到了更好的方法,请告诉我。

2 个答案:

答案 0 :(得分:2)

根据这个帖子:http://osdir.com/ml/java-tynamo-user/2012-04/msg00005.html,这只是一个COMMIT问题:)。

在标准上下文中,事务由调用服务的Page处理。在REST方法中,这项工作应由服务本身完成。

确实,我们的想法是将您自动发现的REST服务更改为真正的挂毯IOC。

1 - 将其从自动发现中移开

将其移至服务包(或允许Tapestry绑定但不在其余自动发现包中的任何人):

2 - 提取界面

提取界面,并在其上添加注释+ CommitAfter您要处理事务的位置。

package com.myorg.mobile.pushup.services.user;

@Path("/user")
public interface IUserResource {

    /**
     * Lecture de tous les utilisateurs
     * 
     * @return une List des utilisateurs existants
     */
    @GET
    @Produces("application/json")
    List<User> getAllDomains();


    /**
     * Méthode d'enregistrement / MAJ d'un utilisateur.
     * 
     * @param user
     *            l'utilisateur à créer
     * @return
     */
    @POST
    @PUT
    @Produces({ "application/xml", "application/json" })
    @Consumes({ "application/xml", "application/json" })
    @CommitAfter
    Response registerOrUpdate(User user);
}

删除实施

上的注释
package com.myorg.mobile.pushup.services.user.impl;

public class HibernateUserResourceImpl implements IUserResource {
    /* (non-Javadoc)
     */

    public List<User> getAllDomains() {

        return session.createCriteria(User.class).list();
    }

    /* (non-Javadoc)
     */

    Response registerOrUpdate(User user);
        session.saveOrUpdate(user);
        return Response.ok().build();
    }

3 - 将其作为单身资源

public class AppModule {
    public static void bind(ServiceBinder binder) {
        binder.bind(IUserResource.class, HibernateUserResourceImpl.class);
    }

    /**
     * Contributions to the RESTeasy main Application, insert all your RESTeasy
     * singletons services here.
     */
    @Contribute(javax.ws.rs.core.Application.class)
    public static void configureRestResources(Configuration<Object> singletons,
            IUserResource userResource) {
        singletons.add(userResource);
    }

}

4 - 建议注释它们是交易的方法

public class AppModule {

    @Match("*Resource*")
    public static void adviseTransactionally(
            HibernateTransactionAdvisor advisor, MethodAdviceReceiver receiver) {

        advisor.addTransactionCommitAdvice(receiver);
    }

如果您更喜欢使用JPATransactionAdvision而不是Hibernate,可以添加其他依赖项:

    <dependency>
        <groupId>org.tynamo</groupId>
        <artifactId>tapestry-jpa-core</artifactId>
        <version>2.0.1</version>
    </dependency>

5 - 结论

这个解决方案对我有用,但据我所知,这实际上是唯一的方法。

Alejandro&gt;如果您阅读这些内容,请告诉我是否还有另一种(最短)方式,我是对的:)

答案 1 :(得分:1)

您可以使用HibernateSessionManager实现(在tapestry-hibernate依赖内部)来获取会话并立即提交数据,如下所示

@Inject 
HibernateSessionManager hibernateSessionManager;

public  void saveOrUpdate(MyEntity instance) {
    Session session = hibernateSessionManager.getSession();
    session.saveOrUpdate(instance);
    hibernateSessionManager.commit();
    session.flush();
}

您无法关闭会话。因为会话是共享的,所以如果你试图关闭会话,你可能会遇到异常,例如&#34; hibernate会话已关闭&#34;。

此处还共享事务,因此您只能使用hibernateSessionManager中给出的commit()函数提交事务,而不知道当前事务。