Hello I Have a problem with my Spring/Hibernate project. I was trying to implement generic classes for DAOs and Services and use one concrete implementation to show something on screen. Everything starts without error, but if i wanna create a new project, after form submisions it throws Stack Overflow error (see image below). I rly cant find out where the problem is. I hope someone here can help me. Below you can see all my code, potentialy can add jsp or config files if necessary. Thanks for your time.
GenericDaoImpl
#SuppressWarnings("unchecked")
#Repository
public abstract class GenericDaoImpl<T, PK extends Serializable> implements IGenericDao<T, PK> {
#Autowired
private SessionFactory sessionFactory;
protected Class<? extends T> entityClass;
public GenericDaoImpl() {
Type t = getClass().getGenericSuperclass();
ParameterizedType pt = (ParameterizedType) t;
entityClass = (Class<? extends T>) pt.getActualTypeArguments()[0];
}
protected Session currentSession() {
return sessionFactory.getCurrentSession();
}
#Override
public PK create(T t) {
return (PK) currentSession().save(t);
}
#Override
public T read(PK id) {
return (T) currentSession().get(entityClass, id);
}
#Override
public void update(T t) {
currentSession().saveOrUpdate(t);
}
#Override
public void delete(T t) {
currentSession().delete(t);
}
#Override
public List<T> getAll() {
return currentSession().createCriteria(entityClass).list();
}
#Override
public void createOrUpdate(T t) {
currentSession().saveOrUpdate(t);
}
GenericServiceImpl
#Service
public abstract class GenericServiceImpl<T, PK extends Serializable> implements IGenericService<T, PK>{
private IGenericDao<T, PK> genericDao;
public GenericServiceImpl(IGenericDao<T,PK> genericDao) {
this.genericDao=genericDao;
}
public GenericServiceImpl() {
}
#Override
#Transactional(propagation = Propagation.REQUIRED)
public PK create(T t) {
return create(t);
}
#Override
#Transactional(propagation = Propagation.REQUIRED, readOnly = true)
public T read(PK id) {
return genericDao.read(id);
}
#Override
#Transactional(propagation = Propagation.REQUIRED)
public void update(T t) {
genericDao.update(t);
}
#Override
#Transactional(propagation = Propagation.REQUIRED)
public void delete(T t) {
genericDao.delete(t);
}
#Override
#Transactional(propagation = Propagation.REQUIRED)
public void createOrUpdate(T t) {
genericDao.createOrUpdate(t);
}
#Override
#Transactional(propagation = Propagation.REQUIRED, readOnly = true)
public List<T> getAll() {
return genericDao.getAll();
}
}
ProjectDaoImpl
#Repository
public class ProjectDaoImpl extends GenericDaoImpl<Project, Integer> implements IProjectDao{
}
ProjectServiceImpl
#Service
public class ProjectServiceImpl extends GenericServiceImpl<Project, Integer> implements IProjectService {
#Autowired
public ProjectServiceImpl(#Qualifier("projectDaoImpl") IGenericDao<Project, Integer> genericDao) {
super(genericDao);
}
}
ProjectController
public class ProjectController {
#Autowired(required = true)
private IProjectService projectService;
#RequestMapping(value = "/projects", method = RequestMethod.GET)
public String listProjects(Model model){
model.addAttribute("project", new Project());
model.addAttribute("listProjects", projectService.getAll());
return "project";
}
//for add and update role both
#RequestMapping(value = "/project/add", method = RequestMethod.POST)
public String addProject(#ModelAttribute("project") Project p){
if( p.getId() == 0){
//new role, add it
projectService.create(p);
} else {
//existing role, call update
projectService.update(p);
}
return "redirect:/projects";
}
#RequestMapping("/remove/{id}")
public String deleteProject(#PathVariable("id") int id){
projectService.delete(projectService.read(id));
return "redirect:/projects";
}
#RequestMapping("edit/{id}")
public String editProject(#PathVariable("id") int id, Model model){
model.addAttribute("project", projectService.read(id));
model.addAttribute("listProjects", projectService.getAll());
return "project";
}
}
#Override
#Transactional(propagation = Propagation.REQUIRED)
public PK create(T t) {
return create(t);
}
This method is calling itself unconditionally. This can only result in a StackOverflowError.
Did you mean to do this?
#Override
#Transactional(propagation = Propagation.REQUIRED)
public PK create(T t) {
return genericDao.create(t);
}
Related
I'm working on an Android App that use SQLCipher, ORMLite for Android to handle to POJO storing with SQLite and Jackson for parsing.
I'm wondering if there would be a better pattern that the one i'm using (Recommended by stayforit) to get the DAO corresponding to the Entity class given. I have over 30 Entity class and I keep adding some over the time and each time, I have to create a DAO class that looks exactly the same as the previous one. How could I generalize using a generic class?
Here is my DbManager class:
public class DbManager {
private static DbManager instance;
private CipherDbHelper dbHelper;
private SecureSharedPreferences settings;
private DbManager() {
}
private DbManager(Context context, String password) {
SQLiteDatabase.loadLibs(context);
dbHelper = new CipherDbHelper(context, password);
}
public static void init(Context context, String password) {
instance = new DbManager(context, password);
}
public static DbManager getInstance() {
if (instance == null) {
Log.e("DbManager", "DbManager is null");
}
return instance;
}
public <D extends Dao<T, String>, T> D getDAO(Class<T> clz) throws SQLException {
return dbHelper.getDao(clz);
}
}
Here is an example of a recurrent DAO class I need to generate each time I add a POJO entity to my project:
public class CategoriesDAO extends BaseDAO<EntityCategories> {
private static CategoriesDAO instance;
private CategoriesDAO() {
}
public synchronized static CategoriesDAO getInstance() {
if (instance == null) {
instance = new CategoriesDAO();
}
return instance;
}
#Override
public Dao<EntityCategories, String> getDAO() throws SQLException, java.sql.SQLException {
return DbManager.getInstance().getDAO(EntityCategories.class);
}
}
Here is how I use it in an Activity:
CategoriesDAO.getInstance().addOrUpdate(categories);
That's the way I like to use Ormlite DAO's:
CRUDOperator:
public interface CRUDOperator<T> {
void create(T obj);
void update(T obj);
void delete(T obj);
}
Repo:
public interface Repo<T> extends CRUDOperator<T>{
Optional<T> queryForId(Integer id);
ObservableList<T> queryForAll();
...
}
OrmliteRepo:
public class OrmliteRepo<T> implements Repo<T> {
protected Dao<T, Integer> dao;
protected OrmliteRepo(Dao<T, Integer> dao) {
this.dao = dao;
}
public ObservableList<T> queryForAll() throws SQLException {
List<T> results = dao.queryForAll();
return Validators.isNullOrEmpty(results) ? FXCollections.observableArrayList() : FXCollections.observableArrayList(results);
}
public Optional<T> queryForId(Integer id) throws SQLException {
T result = dao.queryForId(id);
return Optional.ofNullable(result);
}
#Override
public void create(T obj) throws SQLException {
dao.create(obj);
}
#Override
public void update(T obj) throws SQLException {
dao.update(obj);
}
#Override
public void delete(T obj) throws SQLException {
dao.delete(obj);
}
}
YourRepo:
public class YourRepo extends OrmliteRepo<YourModel> {
public YourRepo(Dao<YourModel, Integer> dao) {
super(dao);
}
}
RepoService:
public interface RepoService {
<T> Repo<T> get(Class<T> dataClass);
}
BaseRepoService:
public class BaseRepoService implements RepoService {
private RepoFactory repoFactory;
private Map<Class<?>, Repo<?>> repoCache;
public BaseRepoService(RepoFactory repoFactory) {
this.repoFactory = repoFactory;
repoCache = new HashMap<>();
}
#Override
public <T> Repo<T> get(Class<T> dataClass) {
#SuppressWarnings("unchecked")
Repo<T> repo = (Repo<T>) repoCache.get(dataClass);
if (repo == null) {
repo = createRepo(dataClass);
repoCache.put(dataClass, repo);
}
return repo;
}
private <T> Repo<T> createRepo(Class<T> dataClass) {
return repoFactory.createRepo(dataClass);
}
}
RepoFactory:
public interface RepoFactory {
public <T> Repo<T> createRepo(Class<T> dataClass);
}
OrmliteRepoFactory:
public class OrmliteRepoFactory implements RepoFactory {
private DbAccess dbAccess;
private final Map<Class<?>, Supplier<OrmliteRepo<?>>> suppliers;
public OrmliteRepoFactory(DbAccess dbAccess) {
this.dbAccess = dbAccess;
suppliers = new HashMap<>();
suppliers.put(YourModel.class, () -> new YourRepo(getDao(YourModel.class)));
}
private <T> Dao<T, Integer> getDao(Class<T> modelClass) {
return dbAccess.getDaoImplementation(modelClass);
}
#Override
#SuppressWarnings("unchecked")
public <T> OrmliteRepo<T> createRepo(Class<T> dataClass) {
return (OrmliteRepo<T>) suppliers.get(dataClass).get();
}
}
DbAccess:
public interface DbAccess {
<T, R> R getDaoImplemantation(Class<T> dataClass);
}
OrmliteDbAccess:
public class OrmliteDbAccess implements DbAccess{
#Override
public <T, R> R getDaoImplementation(Class<T> objectClass) {
R dao = null;
try {
dao = DaoManager.createDao(connectionSource, objectClass);
} catch (SQLException e) {
LOGGER.error("Error getting dao for class {}; {}", objectClass, e);
}
return dao;
}
}
Now all you need to do is add the suppliers for your repos to the repoFactory and make YourRepo.class extend OrmliteRepo.class. If I need some additional behaviour for a specific repo, I put it in that repo implementation.
When you have an instance of RepoService:
RepoService repoService = new BaseRepoService(ormliteRepoFactory);
you can access your repo like this:
Repo<YourModel> repo = repoService.get(YourModel.class);
You could store the instances of your POJO daos in a map either inside your BaseDao itself or in a subclass and then use an unchecked cast to extract it out.
public class GenericDao<T> extends BaseDao<T> {
private static class InstanceHolder {
static final Map<Class<?>, GenericDao<?>> INSTANCES = new HashMap<>();
}
public static synchronized <T> GenericDao<T> getInstance(Class<T> clazz) {
GenericDao<T> dao = (GenericDao<T>)InstanceHolder.INSTANCES.get(clazz);
if (dao == null) {
dao = new GenericDao<T>();
InstanceHolder.INSTANCES.put(clazz, dao);
}
return dao;
}
private GenericDao() {
}
}
and then
GenericDao<EntityCategories> foo = GenericDao.getInstance(EntityCategories.class);
foo.addOrUpdate(....);
This is going to be somewhat long, but I am simply trying to learn fancy things using spring 4.1.7
The problem that I am facing is that spring doesn't like that there is no bean declared for R and W in the Reader and Writer Controllers. Everything compiles but during runtime nothing works and I get error
Error creating bean with name 'userController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: protected carefree.coding.dao.CommerceReaderDAO carefree.coding.controllers.rest.CommerceReaderController.reader; nested exception is java.lang.IllegalArgumentException: Can not set carefree.coding.dao.CommerceReaderDAO field carefree.coding.controllers.rest.CommerceReaderController.reader to com.sun.proxy.$Proxy57
I have a simple DAO class
#MappedSuperclass
public abstract class CommerceObject
{
public enum Type
{
USER
}
#Transient
protected Type type;
#Id
#GeneratedValue
#Column(name = "id")
protected long id;
public CommerceObject(Type type)
{
this.type = type;
setId(-1l);
}
public Type getType()
{
return type;
}
public long getId()
{
return id;
}
public void setId(long id)
{
this.id = id;
}
public boolean equals(CommerceObject object)
{
return getId() == object.getId() && getType().equals(object.getType());
}
#Override
public String toString()
{
return new Gson().toJson(this);
}
public CommerceObject fromString(String json)
{
return new Gson().fromJson(json, getClass());
}
public abstract boolean update(CommerceObject object);
public abstract CommerceObject copy();
#Override
public int hashCode()
{
throw new UnsupportedOperationException("No hashing for game objects");
}
}
Which is extended by
#Entity(name = "user")
public class User extends CommerceObject
{
#Column(name = "email")
private String email;
public User()
{
super(Type.USER);
}
public String getEmail()
{
return email;
}
public void setEmail(String email)
{
this.email = email;
}
#Override
public boolean update(CommerceObject object)
{
if (object instanceof User)
{
User user = (User) object;
if (equals(user))
{
user.setEmail(email);
}
}
return false;
}
#Override
public CommerceObject copy()
{
User user = new User();
user.setEmail(getEmail());
return user;
}
}
For reading and writing things to database I have two interfaces
Reader
public interface CommerceReaderInterface<V extends CommerceObject>
{
#Transactional(readOnly = true)
List<V> get();
#Transactional(readOnly = true)
V get(long id);
}
Writer
public interface CommerceWriterInterface<V extends CommerceObject>
{
#Transactional
V add(V v);
#Transactional
V update(V v);
#Transactional
V delete(V v);
}
Basic database access class
public abstract class CommerceDAO
{
protected SessionFactory sessionFactory;
protected Class aClass;
public CommerceDAO(SessionFactory sessionFactory, Class aClass)
{
this.sessionFactory = sessionFactory;
this.aClass = aClass;
}
}
Which allows reader and writer to exist
Reader
public class CommerceReaderDAO<V extends CommerceObject> extends CommerceDAO implements CommerceReaderInterface<V>
{
public CommerceReaderDAO(SessionFactory sessionFactory, Class aClass)
{
super(sessionFactory, aClass);
}
#Override
public List<V> get()
{
ClassMetadata hibernateMetadata = sessionFactory.getClassMetadata(aClass);
if (hibernateMetadata == null)
{
return null;
}
if (hibernateMetadata instanceof AbstractEntityPersister)
{
AbstractEntityPersister persister = (AbstractEntityPersister) hibernateMetadata;
String tableName = persister.getTableName();
if (tableName != null)
{
return sessionFactory.getCurrentSession().
createQuery(tableName).list();
}
}
return null;
}
#Override
public V get(long id)
{
V object = (V) sessionFactory.getCurrentSession().
get(aClass, id);
Hibernate.initialize(object);
return object;
}
}
Writer
public class CommerceWriterDAO<V extends CommerceObject> extends CommerceDAO implements CommerceWriterInterface<V>
{
public CommerceWriterDAO(SessionFactory sessionFactory, Class aClass)
{
super(sessionFactory, aClass);
}
#Override
public V add(V v)
{
if (v != null)
{
sessionFactory.getCurrentSession().save(v);
return v;
}
return null;
}
#Override
public V update(V v)
{
if (v != null)
{
sessionFactory.getCurrentSession().update(v);
return v;
}
return null;
}
#Override
public V delete(V v)
{
if (v != null)
{
sessionFactory.getCurrentSession().delete(v);
sessionFactory.getCurrentSession().flush();
return v;
}
return null;
}
}
And for controllers I decided to do same thing and have a reader and writer interface
Reader
public interface CommerceReaderInterface
{
#RequestMapping(value = "/get",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<String> get();
#RequestMapping(value = "/get/{id}",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<String> get(#PathVariable long id);
}
Writer
public interface CommerceWriterInterface<V extends CommerceObject>
{
#RequestMapping(value = "/add",
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<String> add(#RequestBody V v);
#RequestMapping(value = "/update",
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<String> update(#RequestBody V v);
#RequestMapping(value = "/delete",
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<String> delete(#RequestBody V v);
}
And they are implemented normally
Reader
public abstract class CommerceReaderController<R extends CommerceReaderDAO<V>, V extends CommerceObject> implements CommerceReaderInterface
{
#Autowired
protected R reader;
#Override
public ResponseEntity<String> get()
{
List<V> list = reader.get();
if (list == null || list.isEmpty())
{
return ResponseUtil.notFound();
}
return ResponseUtil.ok(list);
}
#Override
public ResponseEntity<String> get(#PathVariable long id)
{
V object = reader.get(id);
if (object == null)
{
return ResponseUtil.notFound();
}
return ResponseUtil.ok(object);
}
}
Writer
public abstract class CommerceWriterController<W extends CommerceWriterDAO<V>, R extends CommerceReaderDAO<V>, V extends CommerceObject> extends CommerceReaderController<R, V> implements CommerceWriterInterface<V>
{
#Autowired
protected W writer;
#Override
public ResponseEntity<String> add(#RequestBody V v)
{
v = writer.add(v);
if (v == null)
{
return ResponseUtil.notFound();
}
return ResponseUtil.ok(v);
}
#Override
public ResponseEntity<String> update(#RequestBody V v)
{
v = writer.update(v);
if (v == null)
{
return ResponseUtil.notFound();
}
return ResponseUtil.ok(v);
}
#Override
public ResponseEntity<String> delete(#RequestBody V v)
{
v = writer.delete(v);
if (v == null)
{
return ResponseUtil.notFound();
}
return ResponseUtil.ok(v);
}
}
After all that work I thought that having a simple controller would be allowed
#Controller
#RequestMapping("/commerce/api/user")
public class UserController extends CommerceWriterController<UserWriterDAO, UserReaderDAO, User>
{
}
However as I understand in my abstract controllers I am not allowed to have such vague DAO objects. Is there any way I can circumvent this?
For some reason, my service is returning a null. The autowires are correct, the service annotation is there, the getters and setters .. But this returns a null :
public PlatformService getPlatformService() {
return platformService;
}
public void setPlatformService(PlatformService platformService) {
this.platformService = platformService;
}
on Debug, it returns platformService = null
Here is my PlatformService :
package empsuite.service;
import java.util.List;
import empsuite.model.Platform;
public interface PlatformService {
public void addPlatform(Platform platform);
public void updatePlatform(Platform platform);
public Platform getPlatformById(int id);
public List<Platform> getPlatform();
}
PlatformServiceImpl :
#Service
#Transactional
public class PlatformServiceImpl implements PlatformService {
#Autowired
PlatformDAO platformDAO;
#Transactional(readOnly = false)
public void addPlatform(Platform platform) {
getPlatformDAO().addPlatform(platform);
}
#Transactional(readOnly = false)
public void updatePlatform(Platform platform) {
getPlatformDAO().updatePlatform(platform);
}
private PlatformDAO getPlatformDAO() {
return platformDAO; }
public void setPlatformDAO(PlatformDAO platformDAO) {
this.platformDAO = platformDAO;
}
public Platform getPlatformById(int id) {
return getPlatformDAO().getPlatformById(id);
}
public List<Platform> getPlatform() {
return getPlatformDAO().getPlatform();
}
}
The DAOImpl function (with sessionfactory autowired) as it is the builder of the HQL :
public List<Platform> getPlatform() {
List list = getSessionFactory().getCurrentSession().createQuery("from Platform").list();
return list;
}
#ManagedProperty is the cause of the problem, so I overriden it and it works with this constructor :
public PlatformManagedBean() {
super();
if(platformService == null){
WebApplicationContext ctx = FacesContextUtils.getWebApplicationContext(FacesContext.getCurrentInstance());
platformService = ctx.getBean(PlatformService.class);
}
}
I want to write abstract class, which will contains all generic methods for working with db like save, update and etc. After that create as many implementations as many DAO's I need, and, if needed, overwrite/add methods.
public interface Dao<T, ID extends Serializable> {
void save(T t);
T get(ID id);
void update(T t);
void remove(T t);
List<T> findAll();
}
#Repository
#Transactional
public abstract class AbstractDao<T, ID extends Serializable> implements Dao<T, ID> {
#Autowired
private SessionFactory sessionFactory;
private Class<T> clazz;
public AbstractDao(Class<T> clazz) {
this.clazz = clazz;
}
public void save(T t) {
sessionFactory.getCurrentSession().save(t);
}
public T get(ID id) {
return sessionFactory.getCurrentSession().get(clazz, id);
}
public void update(T t) {
sessionFactory.getCurrentSession().update(t);
}
public void remove(T t) {
sessionFactory.getCurrentSession().delete(t);
}
public List<T> findAll() {
return sessionFactory.getCurrentSession().createCriteria(clazz).list();
}
}
#Repository
#Transactional
public class UserDao extends AbstractDao<User, Integer> {
public UserDao() {
super(User.class);
}
}
public class MainTest {
#Test
public void testName() throws Exception {
ApplicationContext ctx = new AnnotationConfigApplicationContext(HibernateConfig.class);
UserDao userDao = ctx.getBean(UserDao.class);
...
}
}
And I get this error:
No qualifying bean of type [com.sevak-avet.UserDao] is defined
If I don't use AbstractDao class and implement all methods directly in UserDao, it works. What I'm doing wrong?
I run in few huge problems by using getSession() on HibernateDaoSupport and now when i try to fix it I was wondering if it is right to make a abstract class like this bellow and make all Dao's to extend it instead of adding SessionFactory in each Dao ?
If it is, then would creating bean of this abstract Dao class and passing it the session factory then work once other Dao's extend it? Or that is not even possible?
public abstract class AbstractDAOImpl<T> implements
AbstractDAO<T> {
private static Logger _logger = LoggerFactory
.getLogger(AbstractDAOImpl.class);
private SessionFactory factory;
#Override
public void refresh(final T object) {
try {
factory.getCurrentSession().refresh(object);
} catch (Exception e) {
_logger.error("Cannot refresh object " + object, e);
}
}
#Override
public void remove(final T object) {
try {
factory.getCurrentSession().delete(object);
} catch (Exception e) {
_logger.error("Cannot remove object " + object, e);
}
}
#Override
public void save(final T object) {
try {
factory.getCurrentSession().saveOrUpdate(object);
} catch (Exception e) {
_logger.error("Cannot save or update object " + object, e);
}
}
}
public interface RootDAO<T> extends Serializable {
public List<T> loadAll();
public T save(T entity);
public void delete(T entity);
public void markAsDeleted(T entity);
public T get(Serializable id);
public T load(Serializable id);
public void saveOrUpdate(T entity);
public void deleteAll(Collection<T> entities);
public void saveOrUpdateAll(Collection<T> entities);
public List<T> find(String hql);
public void update(T entity);
public T getByExampleUnique(T entity);
public List<T> getByExampleList(T entity);
public List<T> listAll();
public Object execute(HibernateCallback action);
public List<T> findByNamedParam(String queryString, String paramName,Object value);
public List<T> findByNamedParam(String queryString, String[] paramNames,Object[] values);
.
.
.
.
}
#Component
public abstract class RootDAOImpl<T> extends HibernateDaoSupport implements RootDAO<T> {
protected Logger logger = LoggerFactory.getLogger(getClass());
private Class<T> clazz;
#Autowired
public void init(SessionFactory factory) {
setSessionFactory(factory);
}
public RootDAOImpl(Class<T> clazz) {
this.clazz = clazz;
}
public void delete(T entity) {
getHibernateTemplate().delete(entity);
}
public void delete(String id) {
getHibernateTemplate().delete(new FbUser(id));
}
public void markAsDeleted(T entity) {
// Mark entity as deleted
try {
Method setDeletedMethod = clazz.getDeclaredMethod("setDeleted", Boolean.class);
setDeletedMethod.invoke(entity, true);
getHibernateTemplate().saveOrUpdate(entity);
} catch (Exception e) {
e.printStackTrace();
}
// actually delete
// getHibernateTemplate().delete(entity);
}
#Override
public void deleteAll(Collection<T> entities) {
getHibernateTemplate().deleteAll(entities);
}
#Override
public void saveOrUpdateAll(Collection<T> entities) {
getHibernateTemplate().saveOrUpdateAll(entities);
}
#SuppressWarnings("unchecked")
#Override
public T get(Serializable id) {
return (T) getHibernateTemplate().get(clazz, id);
}
#SuppressWarnings("unchecked")
#Override
public T load(Serializable id) {
return (T) getHibernateTemplate().load(clazz, id);
}
#SuppressWarnings("unchecked")
#Override
public List<T> find(String hql) {
return (List<T>) getHibernateTemplate().find(hql);
}
#Override
public Object execute(HibernateCallback action) {
return getHibernateTemplate().execute(action);
}
.
.
.
}
#Repository
public class UserDAOImpl extends RootDAOImpl<User> implements UserDAO{
public UserDAOImpl() {
super(User.class);
}
}
If you are not using a DI framework you may need to keep a reference for SessionFactory and pass it yourself when you create the DAO instance.
This is exactly why people use JPA implementation by hibernate. You just need to start using the JPA's EntityManager which leverages on SessionFactory by itself in the best possible design patterns. You dont have to reinvent the whole design patterns here. All you need to do is just use CRUD operations of EntityManager in each of your DAO as shown in the following example. All the best with your implementation.
http://www.myhomepageindia.com/index.php/2009/04/02/jpa-hibernate-with-oracle-on-eclipse.html