Spring AOP one method of a class before another - java

I have an app using Spring Core, Spring MVC, Hibernate.
There are a lot of DAO classes which get new Hibernate session in every method like this
#Autowired
private SessionFactory sessionFactory;
private Session session;
private void createSession() {
session = sessionFactory.openSession();
}
#Override
public List<User> listUsers() {
createSession();
List users;
users = session.createQuery("from User").list();
session.close();
return users;
}
I would like to use AOP to execute createSession method before those class methods but can't figure out how to do it.
All I have done was this aspect
#Configuration
#Aspect
public class DaoSessionLifeCycle {
#Before(value = "execution(* ua.com.alistratenko.dao.UserDaoImp.listUsers(..))")
public void openSession(JoinPoint joinPoint){
System.out.println("izi");
}
}

Because you still did not provide an MCVE or at least some more (and more realistic) sample code, I can only speculate and provide a schematic answer.
BTW, I am using AspectJ and not Spring AOP here, but it should work the same way there.
Dummy classes to make the sample code compile:
package ua.com.alistratenko.dao;
public class User {
String name;
public User(String name) {
this.name = name;
}
#Override
public String toString() {
return "User [name=" + name + "]";
}
}
package ua.com.alistratenko.dao;
import java.util.ArrayList;
import java.util.List;
public class QueryResult {
public List<User> list() {
List<User> users = new ArrayList<>();
users.add(new User("jane"));
users.add(new User("joe"));
return users;
}
}
package ua.com.alistratenko.dao;
public class Session {
public QueryResult createQuery(String string) {
return new QueryResult();
}
public void close() {}
}
package ua.com.alistratenko.dao;
public class SessionFactory {
public Session openSession() {
return new Session();
}
}
Application class:
What did I change?
In Spring you would use #Autowired instead of creating the session factory by yourself. I just did this in order to be able to run my sample code without Spring.
Added some setters/getters for the aspect to be able to access the session factory and also the session itself
Removed createSession() (code migrated to aspect, see below)
No more boilerplate clutter in listUsers()
Added main method for demo purposes
package ua.com.alistratenko.dao;
import java.util.List;
public class UserDaoImp {
private SessionFactory sessionFactory = new SessionFactory();
private Session session;
public SessionFactory getSessionFactory() { return sessionFactory; }
public Session getSession() { return session; }
public void setSession(Session session) { this.session = session; }
public List<User> listUsers() {
return session.createQuery("from User").list();
}
public static void main(String[] args) {
new UserDaoImp().listUsers();
}
}
Aspect:
In order to do something before + after the intercepted method call, please use #Around.
package de.scrum_master.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
//import org.springframework.stereotype.Component;
import ua.com.alistratenko.dao.UserDaoImp;
//#Component
#Aspect
public class DaoSessionLifeCycle {
#Around("execution(public * listUsers(..)) && target(dao)")
public Object openSession(ProceedingJoinPoint thisJoinPoint, UserDaoImp dao) throws Throwable {
try {
System.out.println("Creating session");
dao.setSession(dao.getSessionFactory().openSession());
System.out.println("Calling " + thisJoinPoint.getSignature());
return thisJoinPoint.proceed();
}
finally {
try {
System.out.println("Closing session");
dao.getSession().close();
}
catch (Exception e) {}
}
}
}
Console log:
Creating session
Calling List ua.com.alistratenko.dao.UserDaoImp.listUsers()
Closing session
Now there are several open questions:
Do you only want to handle this one class or maybe all subclasses of a base class or an implemented interface common to all your DAOs? Then the pointcut would look different.
Do you only want to intercept method listUsers() or maybe also other methods? As you did not show more code, nobody except you can know. The pointcut would also look different depending on your answer.
Do you really want to do this all manually or maybe follow the other users' advice and use on-board Spring tools in order to manage your transactions? I have no idea about Spring, so I cannot tell you. I was just providing the answer to your question which was aspect-related.

In addition to what #Bogdan says, take a look at CrudRepository or JpaRepository, it will save you a lot of time. Also, in my opinion, #Aspect classes are annotated with #Component as opposed to #Configuration.

Related

JPA EntityManager not working when using Guice's PrivateModule

I have a service with a persistence setup using JPA, Hibernate and Guice (if it's useful, I'm not using Spring). This is the first, working version of my code:
public class BookDao {
#Inject
protected Provider<EntityManager> entityManagerProvider;
protected EntityManager getEntityManager() {
return entityManagerProvider.get();
}
#Transactional
public void persist(Book book) {
getEntityManager().persist(book);
}
}
public class MyAppModule extends AbstractModule {
#Override
protected void configure() {
initializePersistence();
}
private void initializePersistence() {
final JpaPersistModule jpaPersistModule = new JpaPersistModule("prod");
jpaPersistModule.properties(new Properties());
install(jpaPersistModule);
}
}
But now I need to configure multiple persistence units. I'm following the advice in this mailing list, and according to them, I should move my module logic to a private module. I did as suggested and created a second version of the same code, the changes are commented below:
#BindingAnnotation
#Retention(RetentionPolicy.RUNTIME)
#Target({ FIELD, PARAMETER, METHOD })
public #interface ProductionDataSource {} // defined this new annotation
public class BookDao {
#Inject
#ProductionDataSource // added the annotation here
protected Provider<EntityManager> entityManagerProvider;
protected EntityManager getEntityManager() {
return entityManagerProvider.get();
}
#Transactional
public void persist(Book book) throws Exception {
getEntityManager().persist(book);
}
}
public class MyAppModule extends PrivateModule { // module is now private
#Override
protected void configure() {
initializePersistence();
// expose the annotated entity manager
Provider<EntityManager> entityManagerProvider = binder().getProvider(EntityManager.class);
bind(EntityManager.class).annotatedWith(ProductionDataSource.class).toProvider(entityManagerProvider);
expose(EntityManager.class).annotatedWith(ProductionDataSource.class);
}
private void initializePersistence() {
JpaPersistModule jpaPersistModule = new JpaPersistModule("prod");
jpaPersistModule.properties(new Properties());
install(jpaPersistModule);
}
}
The newly annotated EntityManager is being correctly injected by Guice and is non-null, but here's the fun part: some of my unit tests started failing, for example:
class BookDaoTest {
private Injector injector;
private BookDao testee;
#BeforeEach
public void setup() {
injector = Guice.createInjector(new MyAppModule());
injector.injectMembers(this);
testee = injector.getInstance(BookDao.class);
}
#Test
public void testPersistBook() throws Exception {
// given
Book newBook = new Book();
assertNull(newBook.getId());
// when
newBook = testee.persist(newBook);
// then
assertNotNull(newBook.getId()); // works in the first version, fails in the second
}
}
In the first version of my code the last line above just works: the entity is persisted and has a new id. However, in the second version of my code (using a PrivateModule and exposing an annotated EntityManager from it) the persist() operation doesn't work anymore, the entity is without an id. What could be the problem? I didn't do any other configuration changes in my environment, and I don't see error messages in the logs. Let me know if you need more details.
It turns out that the problem was the #Transactional annotation. In the first version of my code, Guice automatically adds interceptors for managing the transaction. By doing a debug, I found out that before executing my persist(Book book) method, Guice calls the following method from the com.google.inject.internal.InterceptorStackCallback package:
public Object intercept(Object proxy, Method method, Object[] arguments, MethodProxy methodProxy)
In the second version of my code, when I exposed the persistence unit from a private module the above interceptor was no longer called, leaving my persist operation without transaction handling. This is a known issue and is by design.
As a workaround I had to implement transactions by hand, making my code more verbose. I also had to change the way the entity manager is injected. This solution worked for me:
public class BookDao {
#Inject
#Named(PROD_PERSISTENCE_UNIT_NAME)
private EntityManagerFactory entityManagerFactory;
private EntityManager getEntityManager() {
return entityManagerFactory.createEntityManager();
}
public void persist(Book book) throws Exception {
EntityManager em = getEntityManager();
try {
em.getTransaction().begin();
em.persist(book);
em.getTransaction().commit();
} catch (Exception e) {
em.getTransaction().rollback();
throw e;
} finally {
em.close();
}
}
}
public class MyAppModule extends PrivateModule {
public static final String PROD_PERSISTENCE_UNIT_NAME = "prod";
#Override
protected void configure() {
initializePersistence();
}
private void initializePersistence() {
// persistence unit set to prod DB
final JpaPersistModule jpaPersistModule = new JpaPersistModule(PROD_PERSISTENCE_UNIT_NAME);
// connection properties set to suitable prod values
jpaPersistModule.properties(new Properties());
install(jpaPersistModule);
// expose bindings to entity manager annotated as "prod"
bind(JPAInitializer.class).asEagerSingleton();
bind(PersistService.class).annotatedWith(named(PROD_PERSISTENCE_UNIT_NAME)).to(PersistService.class).asEagerSingleton();
expose(PersistService.class).annotatedWith(named(PROD_PERSISTENCE_UNIT_NAME));
bind(EntityManagerFactory.class).annotatedWith(named(PROD_PERSISTENCE_UNIT_NAME)).toProvider(binder().getProvider(EntityManagerFactory.class));
expose(EntityManagerFactory.class).annotatedWith(named(PROD_PERSISTENCE_UNIT_NAME));
bind(EntityManager.class).annotatedWith(named(PROD_PERSISTENCE_UNIT_NAME)).toProvider(binder().getProvider(EntityManager.class));
expose(EntityManager.class).annotatedWith(named(PROD_PERSISTENCE_UNIT_NAME));
bind(UnitOfWork.class).annotatedWith(named(PROD_PERSISTENCE_UNIT_NAME)).toProvider(binder().getProvider(UnitOfWork.class));
expose(UnitOfWork.class).annotatedWith(named(PROD_PERSISTENCE_UNIT_NAME));
}
}
As a lesson, be very watchful around annotations and other such "magic" that modifies your code under the hood, finding bugs becomes quite difficult.

Mock test not returning any value Java Junit

I am trying to test a method that connects to db using hibernate using junit and mocking.
Here is my code
UserDAO.java
public interface UserDAO {
public void addUser(String username, String password);
public List<String> getUsers();
}
UserDAOImpl.java
public class UserDAOImpl implements UserDAO {
public static final Logger LOG = LoggerFactory.getLogger(UserDAOImpl.class);
private static Session session;
public UserDAOImpl() {
}
public UserDAOImpl(Session session) {
this.session = session;
}
private static void beginSession() {
session = DbUtils.getSessionFactory().openSession();
session.beginTransaction();
}
#Override
public void addUser(String username, String password) {
String encryptedPassword = Utils.encrypt(password);
User user = new User(username, encryptedPassword);
beginSession();
try {
session.save(user);
System.out.println(user.getPassword());
session.getTransaction().commit();
} catch (SQLGrammarException e) {
session.getTransaction().rollback();
LOG.error("Cannot save user", e);
} finally {
session.close();
}
}
#Override
public List<String> getUsers() {
beginSession();
List<String> results = new ArrayList<String>();
String hql = "select username from User";
Query query = null;
try {
query = session.createQuery(hql);
results = query.list();
} catch (HibernateException e) {
LOG.error("Cannot execute query", e);
}
return results;
}
}
TestUserDAOImpl
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import static org.mockito.Mockito.*;
import org.mockito.runners.MockitoJUnitRunner;
#RunWith(MockitoJUnitRunner.class)
public class TestUserDAOImpl {
#Mock
SessionFactory sessionFactory;
#Mock
Session session;
#Before
public void setup() {
when(sessionFactory.getCurrentSession()).thenReturn(session);
}
#Test
public void testCreate() {
// userDAOImpl = new UserDAOImpl(session);
UserDAOImpl userDAOImpl = Mockito.mock(UserDAOImpl.class);
String username = "username";
String password = "password";
userDAOImpl.addUser(username, password);
System.out.println(userDAOImpl.getUsers());
}
}
The test case adds a set of username and password to the db but when I try to return the results using getUsers() it returns a null list.
Can anyone please help me fix this?
First off, you are not adding any users to the DB, because userDAOImpl is a mocked object, therefore, as Joe C has pointed out, the addUser method never gets called on a real object. For the same reason (userDAOImpl is mocked) the getUsers method doesn't return any list.
Just as you have told sessionFactory what to do then its getCurrentSession() method is called, you can tell userDAOImpl what to do when its methods addUser and getUsers get called.
As a side note: the testCreate() method should not contain a System.out.println method, because JUnit cannot know whether your test should pass or fail. If you are using Mockito, you can use the verify method to make sure certain lines of code are getting executed.
Alternatively, if you want to test your repository, you can use an in-memory database and create real objects to insert data into and read from the database. This way your main database doesn't get polluted with test data. Here's a good article on in-memory test databases.
UPDATE: Testing the UserDAOImpl class using Mockito
The first thing I did is, changed the UserDAOImpl class a bit. The reason being: you can't mock static methods using Mockito (at least not at the moment of writing this post). More on this here.
I'm passing the session object to UserDAOImpl and using that session to begin the transaction, instead of using the static method of DbUtils.
Here's the modified UserDAOImpl class:
package test.mockito;
import java.util.ArrayList;
import java.util.List;
public class UserDAOImpl implements UserDAO {
public static final Logger LOG = LoggerFactory.getLogger(UserDAOImpl.class);
private Session session;
public UserDAOImpl(Session session) {
this.session = session;
}
#Override
public void addUser(String username, String password) {
String encryptedPassword = Utils.encrypt(password);
User user = new User(username, encryptedPassword);
session.beginTransaction();
try {
session.save(user);
System.out.println(user.getPassword());
session.getTransaction().commit();
} catch (SQLGrammarException e) {
session.getTransaction().rollback();
if(LOG != null)LOG.error("Cannot save user", e);
} finally {
session.close();
}
}
#Override
public List<String> getUsers() {
session.beginTransaction();
List<String> results = new ArrayList<String>();
String hql = "select username from User";
Query query = null;
try {
query = session.createQuery(hql);
results = query.list();
} catch (HibernateException e) {
if(LOG != null)LOG.error("Cannot execute query", e);
}
return results;
}
}
Let's see how you can test the methods of UserDAOImpl using mocked objects. Initially, we mock objects that we are not testing, but we need them in order to execute statements of the code under test.
package test.mockito;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
#RunWith(MockitoJUnitRunner.class)
public class UserDAOImplTest {
#Mock
Session session;
#Mock
Transaction transaction;
#Before
public void setUp() {
when(session.getTransaction()).thenReturn(transaction);
}
#Test
public void addUserTest() {
UserDAO userDAO = new UserDAOImpl(session);
userDAO.addUser("testusername", "testpassword");
try {
verify(session).getTransaction();
verify(session.getTransaction()).commit();
} catch (SQLGrammarException e) {
fail(e.getMessage());
}
verify(session).close();
}
}
Note: we are not testing Session, neither are we testing Transaction; therefore we are providing these objects to our UserDAOImpl class using Mockito. We assume that methods save(User user), commit(), and other methods of mocked objects, are working properly, so we only test the addUser method. Using Mockito we don't need to establish a real session to the database, but mock the object instead, which is much easier and faster (moreover, it makes it possible to test the addUser method even if we haven't developed yet the other parts of the code - some other developer may be working on that).
In the test case above, the addUserTest() method, tests if this method executes properly when the methods of mocked objects behave as they are expected to. By using verify(session.getTransacion()).commit() we make sure that the commit() method is called, otherwise in the catch block the test fails.
In the same way we can test if addUser rolls the transaction back when an exception is thrown. Here's how you can do it:
#Test
public void addUserTestFails() {
UserDAO userDAO = new UserDAOImpl(session);
try {
doThrow(new SQLGrammarException()).when(session).save(any());
userDAO.addUser("testusername", "testpassword");
verify(transaction, never()).commit();
} catch (SQLGrammarException e) {
verify(transaction).rollback();
}
}
This test case, tests the addUser method if it behaves as excepted when there's an exception thrown while saving the changes. You simulate the exception by telling the mocked object to throw an exception when the save method is called using this piece of code doThrow(new SQLGrammarException()).when(session).save(any());, and then you make sure that the commit() method is never called using verify(transaction, never()).commit();. In the catch block you verify that the transaction is rolled back: verify(transaction).rollback().
Here's the complete class that contains these two test cases:
package test.mockito;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
#RunWith(MockitoJUnitRunner.class)
public class UserDAOImplTest {
#Mock
Session session;
#Mock
Transaction transaction;
#Before
public void setUp() {
when(session.getTransaction()).thenReturn(transaction);
}
#Test
public void addUserTest() {
UserDAO userDAO = new UserDAOImpl(session);
userDAO.addUser("testusername", "testpassword");
try {
verify(session).getTransaction();
verify(session.getTransaction()).commit();
} catch (SQLGrammarException e) {
fail(e.getMessage());
}
verify(session).close();
}
#Test
public void addUserTestFails() {
UserDAO userDAO = new UserDAOImpl(session);
try {
doThrow(new SQLGrammarException()).when(session).save(any());
userDAO.addUser("testusername", "testpassword");
verify(transaction, never()).commit();
} catch (SQLGrammarException e) {
verify(transaction).rollback();
}
}
}
Suggestion: step back. Now.
There is no point in using JUnit and Mockito for testing hibernate and DOAs ... when you lack the basic understanding how to write unit tests in the first place. In your code:
#Test
public void testCreate() {
// userDAOImpl = new UserDAOImpl(session);
UserDAOImpl userDAOImpl = Mockito.mock(UserDAOImpl.class);
String username = "username";
String password = "password";
userDAOImpl.addUser(username, password);
System.out.println(userDAOImpl.getUsers());
}
almost nothing makes sense. A typical unit test goes more like:
class UnderTest {
Foo foo;
UnderTest(Foo foo) { this.foo = foo; }
int bar(String whatever) { return foo.bar(whatever); }
}
class UnderTestTest {
#Mock
Foo foo;
UnderTest underTest;
#Before
public void setup() { underTest = new UnderTest(foo); }
#Test
public void testBar() {
when(foo.bar(any()).thenReturn(5);
assertThat(underTest.bar(), is(5);
}
}
Notes:
You don't mock the class you intend to test. You mock those objects that your class under test needs to do its job; but then, you still mock only those objects that you have to mock to make the test pass.
You then call a method on your object under test; and you either assert that some expected result comes back; or you using mock verification to check that the expected calls on your mocked objects took place.
Long story short: you should rather spent a few days reading tutorials about JUnit and Mockito. In other words: learn to crawl before going for the hurdle race!

Hibernate: Best way of using the `SessionFactory`

I am developing a web application with pure JSP, Servlet and Hibernate. Last few days I was having a trouble with the SessionFactory of Hibernate, not knowing the best way of implementing it. In various places developers have claimed that there should be one SessionFactory for the application. So, I created a singleton class like below.
package dao;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
public class SessionFactoryBuilder
{
private static SessionFactoryBuilder instance;
private static SessionFactory sessionFactory;
private SessionFactoryBuilder()
{
buildConfig();
}
private static void buildConfig()
{
Configuration configuration = new Configuration().configure();
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties());
sessionFactory = configuration.buildSessionFactory(builder.build());
}
public static SessionFactoryBuilder getInstance()
{
if(instance == null)
{
instance = new SessionFactoryBuilder();
}
return instance;
}
public SessionFactory getSessionFactory()
{
return sessionFactory;
}
}
Below is a class which uses the SessionFactoryBuilder.
public class AgentImpl implements AgentInterface
{
SessionFactoryBuilder sessionFactory = SessionFactoryBuilder.getInstance();
#Override
public Session openCurrentSession() {
Session currentSession = sessionFactory.getSessionFactory().openSession();
return currentSession;
}
#Override
public Transaction openTransaction(Session session) {
Transaction beginTransaction = session.beginTransaction();
return beginTransaction;
}
#Override
public void save(Agent entity, Session session) {
session.save(entity);
}
#Override
public void update(Agent entity, Session session) {
session.update(entity);
}
}
Now my question is, is this is the best way of using the SessionFactory ? This might sound like a silly question but it will not when you think about multi threaded behavior in servlets, Driver#Connect error happening because of incorrect usage of session factory, various ways of implementing the singleton pattern and so on. Please provide me your advice.

Hibernate, Spring, querying in non-managed bean causes SessionException

I have a simple entity - Team, with name and rating properties (or maybe more).
Suppose I need to query my teams by multiple criteria.
So instead of adding multiple methods with signature like 'findByXYZAndZYX' to my service, I'd rather add following method :
Teams findTeams()
Implementation snippet:
#Autowired private SessionFactory sessionFactory;
...
#Override
public Teams getTeams() {
return new HibernateTeams(sessionFactory);
}
Now, Teams interface:
public interface Teams extends Iterable<Team> {
Teams withNameContaining(String name);
Teams withRatingGreaterThan(Integer rating);
}
and hibernate-specific implementation:
public class HibernateTeams implements Teams {
private static final String NAME_PROPERTY = "name";
private static final String RATING_PROPERTY = "rating";
private SessionFactory sessionFactory;
private Criteria criteria;
public HibernateTeams(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
criteria = getRootCriteria();
}
private Criteria getRootCriteria() {
return getCurrentSession().createCriteria(Team.class);
}
#Override
public HibernateTeams withNameContaining(String name) {
criteria.add(Restrictions.like(NAME_PROPERTY, name));
return this;
}
#Override
public Teams withRatingGreaterThan(Integer rating) {
criteria.add(Restrictions.gt(RATING_PROPERTY, rating));
return this;
}
#Override
public Iterator<Team> iterator() {
#SuppressWarnings("unchecked")
Collection<Team> result = criteria.list();
return result.iterator();
}
private Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
}
But now, using this in client code:
teamService
.getTeams()
.withNameContaining("someTeamName")
.withRatingGreaterThan(15)
I have an SessionException
org.hibernate.SessionException: Session is closed
I suppose this happens because of passing sessionFactory to non-managed class.
So there are a couple of questions here:
1) Is it possible to do this the way I wrote it? I tried to annotate my HibernateTeams with Transactional or sth, but it didn't help.
2) If I need to make my HibernateTeams spring-managed-bean and possibly inject SessionFactory into it, how can I do that? I've already tried with
#Component #Scope("prototype")
or #Configurable
but with no luck.
Thanks,

HibernateUtil with JPA

I can't figure out what HibernateUtil is ...
Is it required with JPA?
I use JPA with GWT , is this implementation sufficient?
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public final class EMF {
private static final EntityManagerFactory emfInstance =
Persistence.createEntityManagerFactory("default");
private EMF() {}
public static EntityManagerFactory get() {
return emfInstance;
}
}
And at the use:
public class AccountDao {
public static final EntityManager entityManager() {
return Emf.get().createEntityManager();
}
public void createAccount(Account account) {
EntityManager em = entityManager();
EntityTransaction tx = em.getTransaction();
try {
tx.begin();
em.persist(account);
tx.commit();
}
catch (Throwable t) {
t.printStackTrace();
tx.rollback();
}
finally {
em.close();
}
}
}
See this post (Gilead JPA configuration) please. I can't understand yet, how to use HibernateUtil, or HibernateJpaUtil, or PersistentBeanManager stuff ...
To use Gilead with GWT, first change your GWT-RPC service implementations from
public class MyServiceImpl extends RemoteServiceServlet implements MyService {
....
}
into:
public class MyServiceImpl extends PersistentRemoteService implements MyService {
....
}
Then, in the constructor of these classes, call the method setBeanManager(beanManager). Perform the setup as I described in my other answer. Here's the entire code snippet for reference:
public class MyServiceImpl extends PersistentRemoteService implements MyService {
public MyServiceImpl() {
EntityManagerFactory emf = EMF.get();
HibernateJpaUtil hibernateJpaUtil = new HibernateJpaUtil();
hibernateJpaUtil.setEntityManagerFactory(emf);
PersistentBeanManager persistentBeanManager =
GwtConfigurationHelper.initGwtStatelessBeanManager(hibernateJpaUtil);
setBeanManager(persistentBeanManager);
}
// Service methods follow here
}
This is sufficient for the setup - Gilead then uses the bean manager (and HibernateJpaUtils) automatically under the covers, you don't have to interact directly with it. All you have to do is to make sure, that your entities extend net.sf.gilead.pojo.gwt.LightEntity.
Your implementation is pretty sufficient. I would put the factory in the servlet context, rather than making it static though.
But note an important thing here. The above code will work if you are using it purely on the server-side.
Since you are using GWT, it is possible (although I don't think it is rational) to use hibernate "stuff" on the client-side. For that you'd need gilead, where you will need the forementioned utilities.

Categories

Resources