JPA EntityManager not being injected in Java EE app - java

I am receiving a NullPointerException with the following code and configuration, and I am not sure why. I would appreciate some help in debugging this issue.
File persistence.xml:
<persistence-unit name="adismPersistenceUnit" transaction-type="RESOURCE_LOCAL" >
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.adism.domain.Ad</class>
<properties>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/adism" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
<property name="hibernate.connection.username" value="root" />
<property name="hibernate.connection.password" value="" />
</properties>
</persistence-unit>
Entity Class:
#Entity #Table(name = "ads") public class Ad {
private Integer adId;
private String adTitle;
public Ad(){}
#Id
#Column(name="adid")
#GeneratedValue
public Integer getAdId(){
return adId;
}
public void setAdId(Integer adId){
this.adId = adId;
}
#Column(name="adtitle")
public String getAdTitle(){
return this.adTitle;
}
public void setAdTitle(String title){
this.adTitle = title;
}
}
DAO Implementation:
public class AdDaoImpl implements AdDao{
#PersistenceContext
public EntityManager entityManager;
#Override
public void save(Ad ad){
entityManager.persist(ad);
}
}
When I run following code in JSP, I get NullPointerException
Ad ad = new Ad();
ad.setAdId(1000);
ad.setAdTitle("JPA pure");
AdDao newDao = new AdDaoImpl();
newDao.save(ad);

If you just do AdDao newDao = new AdDaoImpl(); your container will not known where to inject the EntityManager.
If you are using JBoss or Glassfish (or someother kind of EJB Containner) you need to declare AdDao as EJB:
#Stateless
public class AdDao () {}
And you will use it in your servlet like:
#EJB
public AdDao ejb;
PS.: I would not inject a DAO in a controller. The best is to use other classes between both, but if you are new to this kind of technology start with it.
If you are using a solution without JPA you can do something like:
private static EntityManagerFactory emf = Persistence.createEntityManagerFactory("YOUR_PERSISTENCE_UNIT"); // store it in your class
public void yourMethod(){
final EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
// do your stuff here
entityManager.getTransaction().commit();
entityManager.close();
}

Related

Why am I getting message about failed altering table while I am only mapping classes to tables at test launch?

At the start of tests, I am mapping many tables from Oracle DB to java classes. Just now I am running only one test query and it runs OK. (Thank SO!)
I have turned on the messages and at the stage of context creation and tables mapping I see not only many successful table findings but in the end, several messages such as:
TST-[2020/12/02 23:58:53.715] hbm2ddl.SchemaUpdate HHH000388: Unsuccessful: alter table CIS_LOKAL_ROLE_AAA add KOD_LOKAL_ROLA_AAA varchar2(10 char) not null
TST-[2020/12/02 23:58:53.715] hbm2ddl.SchemaUpdate ORA-01758: table must be empty to add mandatory (NOT NULL) column
TST-[2020/12/02 23:58:53.881] hbm2ddl.SchemaUpdate HHH000388: Unsuccessful: alter table P01_OPRAVNENI add constraint FK_c0cufehvbvpf9y3dh0fcjrhak foreign key (ID_OBJEKTU) references R01_RIZENI
TST-[2020/12/02 23:58:53.881] hbm2ddl.SchemaUpdate ORA-02298: cannot validate (SPR.FK_C0CUFEHVBVPF9Y3DH0FCJRHAK) - parent keys not found
Why does hibernate want to alter tables at the time of mapping?
Please, note, that there are questions about the similar messages here on SO, but they touch situations when the tables really are to be altered and fail. While I don't want to alter them, the only query is about a counting query, and that is successful and comes after the problems I am writing about.
testng class:
#Test//(enabled = false)
#ContextConfiguration(locations={ "classpath:beans_sets/UhradyForIns.xml"/* , "classpath:beans_sets/mvc-config.xml"*/})
#TransactionConfiguration(transactionManager="transactionManager", defaultRollback=false)
#DirtiesContext(classMode= DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class OdeslatJakobyAutomatickyUhraduTest extends TestBaseWithProperties {
private static final Logger log = LoggerFactory.getLogger(OdeslatJakobyAutomatickyUhraduTest.class);
#Autowired( required = true )
U01UhradaBaseJpaDaoForTesting dao;
#Transactional
#Test
public void odeslat(){
if(dao == null){
Assert.fail("Null context.");
}
dao.setRecordsForSending();
Reporter.log(new String("Number of uhrady to send = "+dao.countUhradyToSend()));
//List<U01Uhrada> uhrady = dao.findUhradyProPoslani();
}
}
public class U01UhradaBaseJpaDaoForTesting {
#PersistenceContext(unitName="SprUnit")
protected EntityManager em;
void setRecordsForSending(){
}
long countUhradyToSend(){
QU01Uhrada uh = QU01Uhrada.u01Uhrada;
JPAQuery jq = new JPAQuery(em);
jq.from(uh);
jq.where(uh.preposlano.eq(U01UhradaPreposlanoEnum.K_PREPOSLANI.asKod()));
return jq.count();
}
}
public class TestBaseWithProperties extends AbstractTestNGSpringContextTests {
{
//---------------------------------- setting paths
// absolute path up to main-app
String mainApp = System.getProperty("user.dir");
String apv = mainApp.substring(0, mainApp.lastIndexOf("\\"));
System.setProperty("main.app", mainApp);
System.setProperty("main.web.webinf", apv + "/main-web/src/main/webapp/WEB-INF");
System.setProperty("spr.root.dir", mainApp + "/work");
// -------------------------------------- setting DB
System.setProperty("database.driver", "oracle.jdbc.driver.OracleDriver");
System.setProperty("database.url", "jdbc:oracle:thin:#oradb2.companyname.com:1534:INPD12");
System.setProperty("database.user", "user");
System.setProperty("database.password", "pass");
}
}
UhradyForIns.xml:
<import resource="classpath:META-INF/spring/spr-properties.xml" />
<!-- Database setting -->
<!--<context:property-placeholder location="classpath:beans_sets/database-test.properties"/>-->
<bean id="dataSourceBean"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${database.driver}"/>
<property name="url" value="${database.url}"/>
<property name="username" value="${database.user}"/>
<property name="password" value="${database.password}"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="file:${main.app}/src/test/resources/beans_sets/persistence-spr-test.xml"/>
<property name="persistenceUnitName" value="SprUnit"/>
<property name="dataSource" ref="dataSourceBean"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="true" />
</bean>
</property>
</bean>
<!-- Automatic Transaction Participation-->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="U01UhradaBaseJpaDaoForTesting" class="amcssz.spr.srv.main.jobs.U01UhradaBaseJpaDaoForTesting"/>
persistence-spr-test.xml
<persistence-unit name="SprUnit" transaction-type="RESOURCE_LOCAL" >
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/spr-db</jta-data-source>
<class>amcssz.spr.srv.main.entity.P01Opravneni</class>
....
<class>amcssz.spr.srv.main.entity.cis.CisLokalRoleAaa</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<!-- Scan for annotated classes and Hibernate mapping XML files -->
<property name="hibernate.archive.autodetection" value="class" />
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.max_fetch_depth" value="3" />
<property name="hibernate.show_sql" value="true" />
</properties>
</persistence-unit>
The entities of the problem tables:
#Entity
#Table(name="CIS_LOKAL_ROLE_AAA")
public class CisLokalRoleAaa extends AbstractCisEntity implements Serializable {
private static final long serialVersionUID = -1302716162506083142L;
#Id //that column exists in the table
#Column(name="KOD_LOKAL_ROLA_AAA", unique=true, nullable=false, length=10)
private String kodLokalRole;
#Column(name="KOD_PRACOVISTE", length=10)
private String kodPracoviste;
public CisLokalRoleAaa() {
}
public String getKodLokalRole() {
return kodLokalRole;
}
public void setKodLokalRole(String kodLokalRole) {
this.kodLokalRole = kodLokalRole;
}
public String getKodPracoviste() {
return kodPracoviste;
}
public void setKodPracoviste(String kodPracoviste) {
this.kodPracoviste = kodPracoviste;
}
}
#Entity
#Table(name="P01_OPRAVNENI")
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "KOD_TYP_OBJEKTU", discriminatorType = DiscriminatorType.STRING)
public class P01Opravneni extends AbstractUpdateable implements Serializable {
private static final long serialVersionUID = -3009052816433258266L;
#Id
#SequenceGenerator(name="P01_OPRAVNENI_IDR02OPRAVNENIRIZENI_GENERATOR", sequenceName="SEQ_P01_OPRAVNENI")
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="P01_OPRAVNENI_IDR02OPRAVNENIRIZENI_GENERATOR")
#Column(name="ID_P01_OPRAVNENI", unique=true, nullable=false, precision=22)
private Long idP01Opravneni;
#Temporal( TemporalType.TIMESTAMP)
#Column(name="DATINS")
private Date datins;
#Column(name="JE_AKTUALNI", nullable=false, precision=1)
private Boolean jeAktualni;
#Column(name="VYMAHAC", nullable=false, length=44)
private String vymahac;
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="KOD_TYP_OBJEKTU", referencedColumnName="KOD_OBJEKT",nullable=false, insertable=false, updatable=false)
private CisObjekt cisObjekt;
#Column(name="KOD_TYP_OBJEKTU",nullable=false, insertable=false,updatable=false)
private String kodTypObjektu;
#Column(name="ID_OBJEKTU", nullable=false)
private Long idObjektu;
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="KOD_PRACOVISTE", insertable=false, updatable=false)
private CisPracovisteCssz cisPracovisteCssz;
#Column(name="KOD_PRACOVISTE", precision=10)
private String kodPracoviste;
#Column(name="prevzato_do")
private Date prevzatoDo;
public Long getIdObjektu() {
return idObjektu;
}
public void setIdObjektu(Long idObjektu) {
this.idObjektu = idObjektu;
}
public String getKodTypObjektu() {
return kodTypObjektu;
}
public void setKodTypObjektu(String kodTypObjektu) {
this.kodTypObjektu = kodTypObjektu;
}
public P01Opravneni() {
}
public Long getIdP01Opravneni() {
return idP01Opravneni;
}
public void setIdP01Opravneni(Long idP02Opravneni) {
this.idP01Opravneni = idP02Opravneni;
}
public Date getDatins() {
return datins;
}
public void setDatins(Date datins) {
this.datins = datins;
}
public Boolean getJeAktualni() {
return this.jeAktualni;
}
public void setJeAktualni(Boolean jeAktualni) {
this.jeAktualni = jeAktualni;
}
public String getVymahac() {
return this.vymahac;
}
public void setVymahac(String vymahac) {
this.vymahac = vymahac;
}
public CisObjekt getCisObjekt() {
return this.cisObjekt;
}
public void setCisObjekt(CisObjekt cisObjekt) {
this.cisObjekt = cisObjekt;
}
public CisPracovisteCssz getCisPracovisteCssz() {
return this.cisPracovisteCssz;
}
public void setCisPracovisteCssz(CisPracovisteCssz cisPracovisteCssz) {
this.cisPracovisteCssz = cisPracovisteCssz;
}
public String getKodPracoviste() {
return kodPracoviste;
}
public void setKodPracoviste(String kodPracoviste) {
this.kodPracoviste = kodPracoviste;
}
public Date getPrevzatoDo() {
return prevzatoDo;
}
public void setPrevzatoDo(Date prevzatoDo) {
this.prevzatoDo = prevzatoDo;
}
}

Manual dynamic enhancement with openjpa on intellij

I am trying to use openjpa and mysql to persist a single class, nothing dramatic really.
Attempt to cast instance "xxx" to PersistenceCapable failed. Ensure that it has been enhanced.
So I looked around and found this
https://openjpa.apache.org/builds/2.2.1/apache-openjpa/docs/ref_guide_pc_enhance.html
where they suggest the use of
java -javaagent:/home/dev/openjpa/lib/openjpa.jar com.xyz.Main
Now I added this to my VM-Options in my intellij runtime configurations:
-javaagent:/home/xxx/Downloads/apache-openjpa-3.1.2/openjpa-all-3.1.2.jar main.java.entity.Post
But it does not seem to recognise the class:
You have enabled runtime enhancement, but have not specified the set of persistent classes. OpenJPA must look for metadata for every loaded class, which might increase class load times significantly.
I thought the 2nd argument for javaagent is me specifiying the class but I am wrong.
This is my persistence.xml:
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.2"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
<!-- Define persistence unit -->
<persistence-unit name="post">
<class>main.java.entity.Post</class>
<properties>
<property name="openjpa.DynamicEnhancementAgent" value="true"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/DSTEST" />
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.user" value="xxx" />
<property name="javax.persistence.jdbc.password" value="xxx" />
</properties>
</persistence-unit>
And this is my entity:
package main.java.entity;
import javax.persistence.Entity;
import javax.persistence.Id;
#Entity (name="post")
public class Post {
#Id
private Integer postid;
private String user;
private Integer datum;
private String inhalt;
public Integer getPostid() {
return postid;
}
public void setPostid(Integer postid) {
this.postid = postid;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public Integer getDatum() {
return datum;
}
public void setDatum(Integer datum) {
this.datum = datum;
}
public String getInhalt() {
return inhalt;
}
public void setInhalt(String inhalt) {
this.inhalt = inhalt;
}
}
I am using Intellij on Ubuntu.

No persistence provider for Entity Manager with Tomcat

I'm trying to to develop a simple rest API project with Java and Tomcat. The HTTP request works correctly, but I'm figuring out a lot of problem by implementing a database MySQL to store data. This is my persistence.xml file, that is located in Java Resources/META-INF:
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="PERSISTENCE">
<description> Hibernate JPA Configuration Example</description>
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>com.resourceserver.Person</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:mysql://localhost:3306/RESTResourceServer" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="password" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
This is my PersonDAO.java and JPAUtil.java class:
public class PersonDao {
EntityManager entityManager;
public PersonDao() {
entityManager = JPAUtil.getEntityManagerFactory().createEntityManager();
}
public void storePerson(Person person) {
entityManager.persist(person);
// people.add(person);
}
public void deletePerson(Person person) {
entityManager.remove(person);
// people.remove(person);
}
public Person findPersonId(int id) {
/*
* for (Person person : people) { if (person.getId() == id) { return person; } }
*/
return null;
}
#SuppressWarnings("unchecked")
public List<Person> getAllUsers() {
Query query = entityManager.createQuery("Select p From People p ");
return query.getResultList();
// return people;
}
}
public class JPAUtil {
private static final String PERSISTENCE_UNIT_NAME = "PERSISTENCE";
private static EntityManagerFactory factory;
public static EntityManagerFactory getEntityManagerFactory() {
if (factory == null) {
factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
}
return factory;
}
public static void shutdown() {
if (factory != null) {
factory.close();
}
}
}
And in my Endpoint I simple use PersonDao persona = new PersonDao() to perform the operations; where am I wrong?
You are missing the persistence provider (no surprise there!)
Most likely you have added the JPA API as a dependency but forgot to add a concrete implementation like Hibernate or EclipseLink. This means you can compile the whole thing because the interfaces for JPA are there but there are not implementing classes.

Creation of the database tables with Hibernate

people!
I made a small project using Servlets / JBoss / Hibernate / Mysql.
I put Hibernate to generate tables automatically. My question is only that: When these table are generated? Tables should be created when I rise the JBoss or when I call the servlet in the browser?
Because I realized that they are created only when I call one of my Servlets, and I imagined they would be created when I rise the JBoss.
Sorry if it's silly.
Here is my Class:
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="estacoes")
public class Estacao {
#Id
#GeneratedValue
private int id;
private String nome;
private String endereco;
private String temperatura;
private String energia;
private String porta;
private String sinal;
private String bateria;
...getters/setters...
My persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="arduinoserver">
<!-- provedor/implementacao do JPA -->
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<non-jta-data-source>java:jboss/datasources/MysqlDS</non-jta-data-source>
<!-- entidade mapaeada -->
<class>arduinoserver.beans.Estacao</class>
<properties>
<!-- propriedades do hibernate -->
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.connection.charSet" value="UTF-8" />
</properties>
</persistence-unit>
And my DAO:
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import arduinoserver.beans.Estacao;
public class EstacaoDAO {
protected EntityManager entityManager;
public EstacaoDAO() {
entityManager = getEntityManager();
}
private EntityManager getEntityManager() {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("arduinoserver");
if(entityManager == null) {
entityManager = factory.createEntityManager();
}
return entityManager;
}
public Estacao getById(final int id) {
return entityManager.find(Estacao.class, id);
}
#SuppressWarnings("unchecked")
public List<Estacao> findAll() {
return entityManager.createQuery("FROM estacoes").getResultList();
}
public void persist(Estacao estacao) {
try {
entityManager.getTransaction().begin();
// entityManager.persist(estacao);
entityManager.merge(estacao);
entityManager.getTransaction().commit();
} catch(Exception ex) {
ex.printStackTrace();
entityManager.getTransaction().rollback();
}
}
}
As far as I know Hibernate creates the tables when the SessionFactory is created. The application server doesn't automatically create one on its own, therefor the tables are usually not created on the server start.

Spring, Hibernate & JPA: Calling persist on entitymanager does not seem to commit to database

I'm trying to setup Spring using Hibernate and JPA, but when trying to persist an object, nothing seems to be added to the database.
Am using the following:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="url" value="${jdbc.url}"/>
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="BankingWeb" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="generateDdl" value="true" />
<property name="showSql" value="true" />
<property name="databasePlatform" value="${hibernate.dialect}" />
</bean>
</property>
</bean>
<tx:annotation-driven/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<bean name="accountManager" class="ssel.banking.dao.jpa.AccountManager" />
<bean name="userManager" class="ssel.banking.dao.jpa.UserManager" />
And in AccountManager, I'm doing:
#Repository
public class AccountManager implements IAccountManager {
#PersistenceContext private EntityManager em;
/* -- 8< -- Query methods omitted -- 8< -- */
public Account storeAccount(Account ac) {
ac = em.merge(ac);
em.persist(ac);
return ac;
}
}
Where ac comes from:
Account ac = new Account();
ac.setId(mostRecent.getId()+1);
ac.setUser(user);
ac.setName(accName);
ac.setDate(new Date());
ac.setValue(0);
ac = accountManager.storeAccount(ac);
return ac;
Is there anyone who can point out what I'm doing wrong? The persist call returns without throwing exceptions. If afterwards I do em.contains(ac), this returns true.
In case anyone needed, here's how Account is defined:
#SuppressWarnings("serial")
#Entity
#NamedQueries({
#NamedQuery(name = "Account.AllAccounts", query = "SELECT a FROM Account a"),
#NamedQuery(name = "Account.Accounts4User", query = "SELECT a FROM Account a WHERE user=:user"),
#NamedQuery(name = "Account.Account4Name", query = "SELECT a FROM Account a WHERE name=:name"),
#NamedQuery(name = "Account.MaxId", query = "SELECT MAX(a.id) FROM Account a"),
#NamedQuery(name = "Account.Account4Id", query = "SELECT a FROM Account a WHERE id=:id"),
})
public class Account extends AbstractNamedDomain {
#Temporal(TemporalType.DATE)
#Column(name = "xdate")
private Date date;
private double value;
#ManyToOne(cascade={CascadeType.PERSIST, CascadeType.MERGE})
#JoinColumn(name="userid")
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
#OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE}, fetch=FetchType.EAGER)
#OrderBy("date")
private List<AccountActivity> accountActivity = new ArrayList<AccountActivity>();
public List<AccountActivity> getAccountActivity() {
return accountActivity;
}
public void setAccountActivity(List<AccountActivity> accountActivity) {
this.accountActivity = accountActivity;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public double getValue() {
return value;
}
public void setValue(double value) {
this.value = value;
}
public void addAccountActivity(AccountActivity activity) {
// Make sure ordering is maintained, JPA only does this on loading
int i = 0;
while (i < getAccountActivity().size()) {
if (getAccountActivity().get(i).getDate().compareTo(activity.getDate()) <= 0)
break;
i++;
}
getAccountActivity().add(i, activity);
}
}
#MappedSuperclass public abstract class AbstractNamedDomain extends AbstractDomain {
private String name;
public AbstractNamedDomain() {
}
public AbstractNamedDomain(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
#MappedSuperclass public abstract class AbstractDomain implements Serializable {
#Id #GeneratedValue
private long id = NEW_ID;
public static long NEW_ID = -1;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public boolean isNew() {
return id==NEW_ID;
}
}
Thanks to eric and Juan Manuel's answers, I was able to figure out that the transaction wasn't committed.
Adding #Transactional to the storeAccount method did the trick!
I actually came across another way that this can happen.
In an injected EntityManager, no updates will ever occur if you have persistence.xml specified like this:
<persistence-unit name="primary" transaction-type="RESOURCE_LOCAL">
You need to remove the transaction-type attribute and just use the default which is JTA.
You do not explicitly need to call the persist method. The merge operation would write the changes to the DB upon commit.
Probably you're keeping the transaction active and it is not calling "commit" until other methods running supporting the active transaction end (all "voting" for commit and none for rollback.)
If you're sure that the entity you're going to persist is ok you could probably do this:
#TransactionManagement(TransactionManagementType.BEAN)
public class AccountManager implements IAccountManager { ..}
and manage your entity persistance adding:
#Resource
private SessionContext sessionContext;
public Account storeAccount(Account ac) {
sessionContext.getUserTransaction().begin();
ac = em.merge(ac);
em.persist(ac);
sessionContext.getUserTransaction().commit();
return ac;
}

Categories