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;
}
}
Related
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
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.
We have set up the Spring Framework like this:
#Eager
public interface CatalogElementRepository extends PagingAndSortingRepository<CatalogElementEntity, Long> {
}
#Service
public class CatalogImpl implements CatalogManager {
#Inject
CatalogElementRepository catalogElementRepository;
#Override
public CatalogElement createCatalogElement(CatalogElementEntity catalogElement) {
return this.catalogElementRepository.save(catalogElement);
}
}
#Stateless
#Remote(CatalogManager.class)
public class CatalogManagerBean implements CatalogManager {
#Inject
CatalogManager delegate;
#Override
public CatalogElement createCatalogElement(CatalogElementEntity catalogElement) {
return this.delegate.createCatalogElement(catalogElement);
}
}
So whenever someone calls the method on the remote interface createCatalogElement, I'd assume the entity gets stored in the database. It does not (weirdly enough, findOne still returns the very same entity, but it can't be found via findByProperty).
Other questions said to add #Transactional, so I added #javax.transaction.Transactional and org.springframework.transaction.annotation.Transactional on the methods and classes to be on the safe side, nothing worked.
What could be the problem?
I don't see any configuration files for the Spring Framework, but it's a legacy project, so they might just be hidden very well.
For some reason using this class as a producer for the EntityManager helped:
public class SpringConfig {
#PersistenceUnit
EntityManagerFactory emf;
#PersistenceContext
EntityManager em;
#Produces
#ApplicationScoped
public EntityManagerFactory createEntityManagerFactory() {
return this.emf;
}
#Produces
public EntityManager createEntityManager() {
return this.em;
}
public void close(#Disposes EntityManagerFactory entityManagerFactory) {
entityManagerFactory.close();
}
public void close(#Disposes EntityManager entityManager) {
entityManager.close();
}
}
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.
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.