使用Hibernate实现Tapestry服务

时间:2013-03-21 14:35:42

标签: java hibernate tapestry

我说的是T5,Java 1.7。

我找不到任何关于在Tapestry服务中使用hibernate的详细教程。 我需要的是创建可以独立处理休眠的Tapestry服务。例如,这可以是调度服务。 此服务将处理DB中的某些对象及其状态,并在应用程序的后台工作。

问题是,如何正确地将其与Hibernate绑定?应该注入哪个Hibernate对象以便在此服务中进一步工作?


当前的方法是在此服务中注入一个HibernateSessionSource对象(通过构造函数传递其实例),然后手动创建会话,开始事务等等。 E.g:

public synchronized void deleteJob(long id) {
    Session session = hss.create();
    JobItem job = (JobItem) session.get(JobItem.class, id);
    if (job != null) {
        Transaction tx = session.beginTransaction();
        try {
            session.delete(job);
            tx.commit();
        } catch (HibernateException e) {
            tx.rollback();
        } finally {
            session.close();
        }
    }
}

它看起来很丑陋,不是Tapestry的风格。什么是聪明的方法?

3 个答案:

答案 0 :(得分:2)

如果您正在处理非挂毯托管服务,则可以使用HibernateSessionManager

try {
   do_stuff(hibernateSessionManager.getSession());
   hibernateSessionManager.commit();
}catch(Exception ex){
   hibernateSessionManager.abort();
}

对于tapestry托管服务和页面/组件,您可以阅读详细文档。这是一些链接

  1. http://tapestry.apache.org/using-tapestry-with-hibernate.html
  2. http://tapestry.apache.org/hibernate-user-guide.html

答案 1 :(得分:2)

这个问题由两部分组成:

如何在tapestry托管服务中使用hibernate?

您可以使用@Inject注释在服务中注入hibernate会话:

@Inject
private Session session;

或作为构造函数参数:

public MyService buildMyService(Session session) {
  return new MyAwsomeService(session);
}

然后你可以在服务中使用它。本次会议由tapestry作为perthread服务进行管理。它将在首次使用时打开,并在请求结束后关闭。

如何在tapestry托管服务中使用hiberanate转换?

您可以使用注入的HibernateSessionManager手动执行此操作:

@Inject
private HibernateSessionManager manager;

public void doSomeWork(Entity entity) {
  try {
    session.delete(entity);
    manager.commit();
  } catch (Exception e) {
    manager.abort();
  }
}

或者您可以使用advise services使用@CommitAfterHibernateTransactionAdvisor注释所有交易方法:

public interface MyService {

  @CommitAfter
  void doSomeWork(Entity entity);

}

public class MyTapestryModule {
  @Match("*Service")
  public void adviseTransactions(HibernateTransactionAdvisor advisor,
                                 MethodAdviceReceiver receiver) {
    advisor.addTransactionCommitAdvice(receiver);
  }
}

或者您可以decorate sevices使用HibernateTransactionDecorator

public class MyTapestryModule {
  @Match("*Service")
  public <T> T decorateTransactions(Class<T> serviceInterface,
                                    T delegate,
                                    String serviceId,
                                    HibernateTransactionDecorator decorator) {
    return decorator.build(serviceInterface, delegate, serviceId);
  }
}

工作原理。它将在方法调用之前启动新事务并尝试在之后提交。如果在方法调用期间发生任何错误,则将回滚此事务。

答案 2 :(得分:1)

您可以直接@Inject会话而不是HibernateSessionManager。

Session tapestry提供的实际上是每个线程,延迟加载代理。底层会话由tapestry管理,并在每次请求后由PerThreadManager清理。

这几乎是魔术!