DAO architecture approach:based on HibernateDaoSupport or on EntityManager - java

I want to manage all DAO in the same way:
1) Create one base class with entity operations like save, update, delete, etc.
2) Each DAO inherits to base class and performs base class operations.
3) All entities also will have one root.
public abstract BaseDao {
...
#Transactional
public T update(T entity) throws DataAccessException {
getHibernateTemplate().update(entity);
return entity;
}
}
...
public MemberDao extends BaseDao {
...
#Override
#Transactional
public IMember update(IMember member) throws DataAccessException {
super.update(member);
return member;
}
}
and there are two possible way:
1) based on HibernateDaoSupport and getHibernateTemplate()
2) based on getEntityManagerFactory().createEntityManager()
Main question is approach based on hibernateTemplate or on entityManager - which of them will be better to use?
Underlying JPA provider in both cases is Hibernate.

Related

I am getting a 'org.hibernate.ObjectDeletedException: deleted instance passed to merge' using 2 different transactions

I am using the Spring Data JPA Repository methods deleteAll() and saveAll(List) in 2 different methods and transactions in a service class. The saveAll(List) method is called to repopulate the table after the deleteAll() call, but I keep getting an org.hibernate.ObjectDeletedException: deleted instance passed to merge error.
#Service
ServiceClass
{
#Autowired MyRepository repository;
public void test()
{
List<myEntity> entities = new ArrayList<>();
//code to populate list
clearTable();
populateTable(entities);
}
#Modifying
#Transactional
private void clearTable()
{
repository.deleteAll();
}
#Modifying
#Transactional
private void populateTable(List<myEntity> entities)
{
repository.saveAll(entities);
}
}
//Repository class
public interface MyRepository extends CrudRepository<myEntity, Long>
{
}
The internal implementation of delete in CrudRepository is as
#Transactional
public void delete(T entity) {
Assert.notNull(entity, "The entity must not be null!");
em.remove(em.contains(entity) ? entity : em.merge(entity));
}
Before an entity removed, this entity must be manage state. We can use some of the function merge, find, etc. Note : After EntityManager is closed, all the entities of its will be detached.
So do a commit after you delete

How to fetch records with base interface for any child implemented class in jpa or hibernate

i have created a Base entity interface with getId() method and implemented into
entities for doing crud operations on all entity save is works and
delete,update also work but retriving by id doesnt work i am not sure its
possible or not if possible then suggest or any other way.
this is base interface for all entities and getId() overrides in each entity
public interface DemoEntity extends Serializable {
public long getId();
}
this is an user entity
public class User implements Serializable,DemoEntity {
getter/setters
}
public class Subject implements Serializable,DemoEntity {
getter/setters
}
//this is modelmanager class for doing crud operations
public class ModelManager {
#Autowired
#PersistenceContext
private EntityManager em;
#Transactional
public void save(DemoEntity entity) {
em.persist(entity);
}
#Transactional
public DemoEntity getEntityById(long id) {
DemoEntity de=em.find(DemoEntity.class, id);
return de;
}
}
#Autowired <-- is not necessary
#PersistenceContext
private EntityManager em;
Your method would looks like better
#Transactional
public DemoEntity getEntityById(long id) {
return em.find(DemoEntity.class, id);
}
and on the top of the class you need to put an annotation like #Component #Repository
And finally you did not say what kind of error you got

How to persist/commit entity to database immediately in Activiti Service Task

I have a need to persist(insert) a entity to database immediately when the save (or saveAndFlush) code is called.
However although the entity is created in the context it is not persisted in the database immediately.
We are using Spring Boot.
public interface MessageRepository extends JpaRepository<MessageEntity, Long> {
}
In the Service class
#Service
public class TestService {
#Autowired
private MessageRepository messageRepository;
#Transactional
public MessageEntity saveMessage(MessageEntity entity) throws Exception {
entity = messageRepository.saveAndFlush(entity);
return entity;
}
}
Though the entity is created it is not persisted/committed to the database immediately.
We are facing this issue within the Activiti Tasks only.
Any feedback will be appreciated.
This worked.
#Component
public class MessageRepositoryCustomImpl implements MessageRepositoryCustom {
#PersistenceContext
EntityManager entityManager;
#Override
#Transactional(propagation = Propagation.REQUIRES_NEW)
public MessageEntity saveImmediate(MessageEntity entity) {
entityManager.persist(entity);
return entity;
}
}
One way of overcoming this situation is by taking advantage of the REQUIRES_NEW transaction attribute.
In your situation you would have to create a new repository:
public interface MessageRepositoryCustom{
void saveAndFLush(MessageEntity ent);
}
public MessageRepositoryCustomImpl implements MessageRepositoryCustom{
#Autowired
private SessionFactory sessionFactory;
#Transactional(propagation = Propagation.REQUIRES_NEW)
void saveAndFLush(MessageEntity ent){
Session session = sessionFactory.getCurrentSession();
session.persist(ent);
}
}
Then in your service you would use that repository:
#Transactional
public MessageEntity saveMessage(MessageEntity entity) throws Exception {
entity = messageRepositoryCutom.saveAndFlush(entity);
// other processing
return entity;
}
}
Now after the messageRepositoryCutom.saveAndFlush method has finished processing the entity will be physically persisted in the database as it was created in a separate transaction which has been commited.

Heavily nested #Transactional annotations

I have inherited a Spring Java codebase where it seems pretty much every method from the business service down to the low level DAOs are tagged with #Transactional. It has some severe performance issues that I noticed are mitigated somewhat when certain annotations are changed from #Transactional(readOnly=false) to #Transactional(readOnly=true). It also seems to have periodic calls to EntityManager.flush() that can't be explained except that certain objects do not get written to the DB without them.
My hunch is that the original developers are misusing/overusing transactions, but I'm not sure of the best approach to clean this up. I would appreciate advice from those more well-versed in Spring Transactions than me.
A reduced example of just one segment of the code follows. There are others much more complex than this with 5-6 levels of nested transactions.
// MVC Controller REST Service
#Controller
#RequestMapping("/service")
public class Group {
#Inject private GroupService groupService;
public #ResponseBody Object update(#RequestBody Group group) {
return groupService.update(group);
}
}
// Business service
#Service
public class GroupService {
#Inject private GroupDAO groupDao;
#Inject private AuditService auditService;
#Transactional(readOnly=false)
public Group update(Group group) {
Group groupToUpdate = groupDao.get(group.getId());
// Do magic
groupDao.persist(groupToUpdate); // Shorthand to call EntityManager.persist()
auditService.logUpdate(group);
return groupToUpdate;
}
}
// DAO
#Repository
public class GroupDAO extends AbstractDAO {
#Transactional(readOnly=true)
public Group get(Long id) {
return entityManager.find(Group.class,id);
}
}
// Auditing service
#Component
public class AuditService {
#Inject AlertDAO alertDao;
#Transactional(readOnly=false)
public void logUpdate(Object o) {
Alert alert = alertDao.getFor(o);
// Do magic
alertDao.update(alert);
alertDao.flush() // Shorthand for EntityManager.flush() but WHY???
}
}
// DAO
#Repository
public class AlertDAO extends AbstractDAO {
#Transactional(readOnly=true)
public Alert getFor(Object forObj) {
// Magic here
return entityManager.find(Alert.class,foundId);
}
#Transactional(readOnly=false)
public void update(Alert a) {
// Magic here
entityManager.merge(a);
}
}
Given that the question is "how to clean up transaction annotations?" the answer would be - based on the above comments;
Do not use transaction annotations in DAOs, only in Services
(#Components)
Make sure DAOs are only called through the
service-layer.

Can I get something like an entity bean in EJB 3.2?

I was reading a Java EE book recently, and apparently entity beans were recently removed from the EJB specification. You are supposed to use JPA instead. But I want entity beans!! What I am really looking for is a JPA persistent entity that is remotely accessible, like an EJB. Something like this:
#Entity
#Remote(MyEntityRemote.class)
#LocalBean
public class MyEntityEJB implements MyEntityRemote {
public void doSomething() {
// actually do something
}
}
Is this at all possible without removing the bean annotations and writing a session bean like this:
#Stateless
#Remote(StatelessInterfaceToMyEntityRemote.class)
#LocalBean
public class StatelessInterfaceToMyEntity implements StatelessInterfaceToMyEntityRemote {
public void doSomething(MyEntity entity) {
entity.doSomething();
}
}
If I understand you correctly it is possible
first you create an Entity:
#Entity
#Table('MyEntityTable')
public class MyEntity {...}
Then you create a session bean facade for the entity exposing through it any interfaces you may need
#Stateless //Facade is a seesion bean so it can be #Stateless or #Statefull for basic CRUD it shoud be #Stateless
public class EntityFacade extends AbstractFacade<MyEntity> {
#PersistenceContext(unitName = "MyPersistanceUnit") //remember to define it first
private EntityManager em;
#Override
protected EntityManager getEntityManager() {
return em;
}
Now u can define any methods that work with your Entity class. Remember if you expose your entity via Remote Interfaces it will be in a detached state. So after updating you will first nee to use the merge(object) method of EntityManager
EDIT
Abstract facade is a concept that is used with JPA Entity, NetBeans in version 7.3 generates it for you automatically. It is used to define the most common operations on Entities so you dont have to repeat the code for every Entity. It goes like this
public abstract class AbstractFacade<T> {
private Class<T> entityClass;
public AbstractFacade(Class<T> entityClass) {
this.entityClass = entityClass;
}
protected abstract EntityManager getEntityManager();
public void create(T entity) {
getEntityManager().persist(entity);
}
public void edit(T entity) {
getEntityManager().merge(entity);
}
public void remove(T entity) {
getEntityManager().remove(getEntityManager().merge(entity));
}
public T find(Object id) {
return getEntityManager().find(entityClass, id);
}
...
}
The function above do some basic CRUD operations without much effort. So extending the facade gives you the ability to have does operations defined you could say out of the box. Of course this just for basic configurations the Entity facade can use many entities and do some business logic before it persists anything. So in your case it would go like this:
public class EntityFacade extends AbstractFacade<MyEntity> {
#PersistenceContext(unitName = "MyPersistanceUnit") //remember to define it first
private EntityManager em;
#Override
protected EntityManager getEntityManager() {
return em;
}
public doSomething(MyEntity entity)
{
entity.get(...);
...
entity.set(...)
if(iWantToPesristIt)
edit(entity)
else
return;
}
}

Categories

Resources