Reputation: 34900
I'm talking about T5, Java 1.7.
I can not find any enough detailed tutorial about using hibernate inside Tapestry services. What I need is to create Tapestry service which could deal with hibernate independently. This could be scheduler service, for example. This service will deal with some objects and their state in DB, and work in background of application.
The question is, how correctly bind it with Hibernate? Which object of Hibernate should be injected for further work inside this Service?
The current approach is to inject inside this service a HibernateSessionSource
object (passing its instance through constructor of service), and then manually create sessions, begin the transactions and so on. 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();
}
}
}
It looks very ugly, not in style of Tapestry. What it is the smart approach?
Upvotes: 0
Views: 1266
Reputation: 504
You can use HibernateSessionManager if you are dealing with non-tapestry managed services.
try {
do_stuff(hibernateSessionManager.getSession());
hibernateSessionManager.commit();
}catch(Exception ex){
hibernateSessionManager.abort();
}
For tapestry managed services and pages/components you can read the detailed documentation. Here are a few links
Upvotes: 2
Reputation: 3791
This question consists of 2 parts:
How to use hibernate inside tapestry managed services?
You can inject hibernate session in your service using @Inject
annotation:
@Inject
private Session session;
or as a constructor parameter:
public MyService buildMyService(Session session) {
return new MyAwsomeService(session);
}
Then you can use it inside service. This session is managed by tapestry as a perthread service. It will be opened on first usage and be closed after end of request.
How to use hiberanate transations inside tapestry managed services?
You can do this manually using injected HibernateSessionManager:
@Inject
private HibernateSessionManager manager;
public void doSomeWork(Entity entity) {
try {
session.delete(entity);
manager.commit();
} catch (Exception e) {
manager.abort();
}
}
Or you can annotate all transactional methods with @CommitAfter
and advise services using HibernateTransactionAdvisor:
public interface MyService {
@CommitAfter
void doSomeWork(Entity entity);
}
public class MyTapestryModule {
@Match("*Service")
public void adviseTransactions(HibernateTransactionAdvisor advisor,
MethodAdviceReceiver receiver) {
advisor.addTransactionCommitAdvice(receiver);
}
}
Or you can decorate sevices using 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);
}
}
How it works. It will start new transaction before method invocation and try to commit after. If any error occurs during method invocation this transaction will be rolled back.
Upvotes: 2
Reputation: 27994
You can @Inject the Session directly instead of the HibernateSessionManager.
The Session tapestry provides is actually a per thread, lazy loading proxy. The underlying session is managed by tapestry and is cleaned up by the PerThreadManager after each request.
It's almost magic!
Upvotes: 1