I'm facing a problem and have no idea what's going wrong. The cenary:
Hibernate 5
Apache Tomcat 9
JSF 2
No Spring. It's important to say because I saw this problem happening realted with Spring use, but this is not my case.
The datasource was correctly configured on Tomcat, and the Hibernate also creates the tables and update schemma correctly for each new Entity.
The problem is when I try to persist a new Entity, nothing happens. Then I tried to include "flush()" call... but then I've got an error saying I have no transaction active:
javax.persistence.TransactionRequiredException: no transaction is in progress
It seems to be a problem related with a transaction requirement, but I have also tried:
include "#Transactional" annotation on method;
include "#Transactional" annotation on class;
Force begin transaction with "beginTransaction()" call but then I've got a NullPointer;
So... I don't know what do to.
Follow you'll see my relevant code. Can you help me to solve this problem?
persistence.xml file:
<persistence-unit name="hospitalPU" transaction-type="RESOURCE_LOCAL">
<description>
Persistence unit for Hibernate
</description>
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<non-jta-data-source>java:comp/env/jdbc/hospitalDatasource</non-jta-data-source>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.default_catalog" value="hospital" />
<property name="hibernate.connection.datasource" value="java:comp/env/jdbc/hospitalDatasource"/>
<property name="hibernate.id.new_generator_mappings" value="false" />
</properties>
</persistence-unit>
My Entity:
#Entity(name="Dominio")
#Table(name="Dominio")
public class Dominio implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue
private Integer id;
here goes another fileds and getters/setters...
On my managed bean, I have:
#PersistenceUnit
private EntityManagerFactory emf;
And:
protected synchronized EntityManager getEntityManager() {
if (emf == null) {
emf = Persistence.createEntityManagerFactory("hospitalPU");
}
return emf.createEntityManager();
}
It seems to work fine, but the problem happens here:
With this, nothing happen and no Exception occours. Just NOTHING happens:
getEntityManager().persist(getDominio());
With this, I have "javax.persistence.TransactionRequiredException: no transaction is in progress":
getEntityManager().persist(getDominio());
getEntityManager().flush(); //exception occours here!
What am I doing wrong? Thanks in advance for you all!
you need to more configure the persistence.xml or hibernate.cfg.xml. you can refer bellow link to configure these xml files.
https://gist.github.com/imanoleizaguirre/3819393
http://www.journaldev.com/7122/jsf-spring-hibernate-integration-example-tutorial
http://www.javaknowledge.info/simple-crud-using-jsf2hibernate-integration-and-mysql/
This one here clearly explains what is the problem:
"javax.persistence.TransactionRequiredException: no transaction is in progress"
First, you have clearly mentioned that you are using a Non-JTA datasource. meaning that the container will no longer manage for you transaction boundaries. You must begin and commit/rollback transactions on your own. You therefore need to follow the following:
EntityManager em = ....
EntityTransaction et = em.getTransaction();
try {
et.begin();
em.persist(entity);
et.commit();
} catch (Exception ex) {
et.rollback();
throw new RuntimeException(ex);
}
Related
I face following issue while trying to write some JBehave BDD test. Scenario is the following:
Due to an MQ message some specific records should be saved into my database and some should be deleted from it. In my #When step I send the given message and in my #Then step I have some asserts to controll the result.
I face issue with the persist and update methods of Hibernate JPA, because it happens just after my code runs to my #Then step and so I got always false result. When I check it in debug mode, and check every recorsd which should be updated / deteled, they are fine.
I assume my asserts should be executed just after the transaction is committed into the database - but this is not the case as I can see.
Is there a way to set a delay or sleep time between database transactions?
Here is e.g. my delete method in my main project:
public void deleteByAbcId(final String Id) {
getEm().createNamedQuery(TABLE.NAMED_QUERY_DELETE_BY_ABC_ID)
.setParameter(Table.QUERY_PARAM_ABC_ID, Id)
.executeUpdate();
}
And in my BDD project I set up database connection as follows:
public class DatabaseService implements Closeable {
private EntityManagerFactory emf = null;
private EntityManager em = null;
/**
* This creates an entity manager based on the db connection parameters received in the argument
*/
public DatabaseService(Properties configuration) {
emf = Persistence.createEntityManagerFactory("project-pu", configuration);
em = emf.createEntityManager();
em.getTransaction().begin();
}
/**
* Returns the entity manager for the db connection
*/
public EntityManager getEm() {
return em;
}
In my assertion I use the following query to check if the given record was successfully removed from the db:
assertNull(dbHelper.findTableIdBasedOnAbcId(Serenity.sessionVariableCalled(ABC_ID)));
My dbHelper class looks like as following:
public class DbHelper {
private DatabaseService database;
private Configuration config = Configuration.getInstance();
public DbHelper() {
database = new DatabaseService(config.getDbProperties());
}
public String findTableIdBasedOnAbcId(String Id) throws Exception {
String query = "SELECT id FROM TABLE WHERE ABC_ID = ?1";
Query queryResult = database.getEm().createNativeQuery(query);
queryResult.setParameter(1, Id);
List<Long> list = (List<Long>) queryResult.getResultList();
if (!list.isEmpty()) {
return String.valueOf(list.get(0));
}
return null;
}
It always retunr the given record of the database, which gets not deleted.
This is the persistence xml of my main project:
<persistence-unit name="aaa-pu" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>jdbc/aaaa-ds</jta-data-source>
<mapping-file>META-INF/orm.xml</mapping-file>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.transaction.jta.platform" value="org.hibernate.engine.transaction.jta.platform.internal.WeblogicJtaPlatform"/>
<property name="hibernate.hbm2ddl.auto" value="none"/>
<property name="hibernate.id.new_generator_mappings" value="false"/>
<property name="tomee.jpa.factory.lazy" value="true"/>
</properties>
</persistence-unit>
And this is the one of my BDD project:
<persistence-unit name="project-pu" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.connection.autocommit" value="false" />
<property name="hibernate.hbm2ddl.auto" value="none" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.generate_statistics" value="false"/>
</properties>
</persistence-unit>
Any idea, how to set transactions not to execute the assert method before the executeUpdate of Hibernate runs?
I tried to call the entityManager.getTransaction.commit method and then start a new one every time but no change.
Is there a way to lock the transaction until the executeUpdate is done and just after that allowing the select query? Or is it possible with JBehave to give a waiting or sleep time between steps?
Thank you.
I want to use Hibernate with H2 and I want the schema to be created automatically. There are many examples online and my configurations seem fine, but it is not created. Previously I used it with MySQL and did not have any problem. Are there additional parameters to be included in anywhere for H2?
My persistence unit is defined in persistence.xml as follows:
<persistence-unit name="some.jpa.name"
transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<!-- tried with and without class property
<class>some.package.KeywordTask</class>
-->
<properties>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:h2:./test" />
<property name="javax.persistence.jdbc.user" value="" />
<property name="javax.persistence.jdbc.password" value="" />
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
<property name="hibernate.hbm2ddl.auto" value="create" />
<property name="show_sql" value="true" />
</properties>
</persistence-unit>
Since show_sql is set to true, I expect to see create statements but nothing happens, i.e. the schema is not created.
I keep my EntityManagerFactory as a final static variable:
public static EntityManagerFactory emf = Persistence.createEntityManagerFactory("some.jpa.name");
In some place in my code, I am trying to persist an entity:
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
KeywordTask task = new KeywordTask();
task.setKeyword(keywordTask.getKey());
task.setLimit(keywordTask.getValue());
em.persist(task);
em.getTransaction().commit();
em.close();
This throws exception with cause:
org.h2.jdbc.JdbcSQLException: Table "KEYWORDTASK" not found;
which is expected since the schema is not created.
How can I get the schema created?
The reason of this problem was quite unrelated! I am writing it here in case some other guys might face it too, and spend half a day for such a stupid thing.
First, I changed from H2 to Derby to check, and it worked. In this way, I was sure that there was no problem with persistence.xml configuration.
After searching around the logs, I realized that hibernate was not able to create the table since one of the properties of the KeywordTask entity was limit, and it is a reserved word! (Remember the place that I persist an instance and observe the name of the setter: setLimit.) After changing the name of the property, it worked.
when execute this java code,that make select from datastore ,an exception was appeared due to first row,so how i can solve this exception?
exception:
javax.persistence.PersistenceException: Explicit persistence provider error(s) occurred for "transactions-optional" after trying the following discovered implementations: org.datanucleus.api.jpa.PersistenceProviderImpl from provider: org.datanucleus.api.jpa.PersistenceProviderImpl
code:
PrintWriter out = resp.getWriter();
try {
EntityManagerFactory emfactory = Persistence
.createEntityManagerFactory("transactions-optional");
EntityManager entitymanager = emfactory.createEntityManager();
javax.persistence.Query query = entitymanager.createQuery("Select u from test u");
List<test> list = (List<test>) query.getResultList();
out.print(list.size());
} catch (Exception e) {
out.println(e.toString());
} finally {
out.close();
}
persistence.xml:
<persistence-unit name="transactions-optional">
<provider>
org.datanucleus.store.appengine.jpa.DatastorePersistenceProviderImpl
</provider>
<properties>
<property name="datanucleus.NontransactionalRead" value="true" />
<property name="datanucleus.NontransactionalWrite" value="true" />
<property name="datanucleus.ConnectionURL" value="appengine" />
</properties>
</persistence-unit>
</persistence>
As the Exception that you posted in the Comments (!) says
org.datanucleus.metadata.InvalidClassMetaDataException: Class s.follows has application-identity and no objectid-class specified yet has 0 primary key fields. Unable to use SingleFieldIdentity.
Yet you don't post this class (why?! don't you think people may want to see it, when it is what the exception is about?).
Solution : mark a field as #Id just like all JPA docs say to.
Update: It seems it's failing after one insert, #412, fails a not null constraint at the database level. The transaction is probably rolling itself back. Given this setup, is it possible to get a new transaction established?
I'm trying to insert a lot of rows into my oracle database, and JPA works just fine until about the 400th insert. I expect to have several thousand rows to insert.
Here's my psuedo-code (shortened for clarity) & persistence.xml:
#Stateless
public class LocalContentService
{
#Inject EntityManager em;
public void mySavingMethod(){
for(Foo foo : fooDao.fetchAllFoos()){
Bar bar = new Bar(foo);
em.persist(bar);
em.flush();
em.clear();
log.debug("Saved content for: " + bar.getId());
}
}
<persistence-unit name="databaseTest" >
<jta-data-source>java:/jdbc/testDS</jta-data-source>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<class>org.myorg.Bar</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="false" />
<property name="hibernate.use_sql_comments" value="true" />
</properties>
</persistence-unit>
After roughly 400 rows, I get this error message and all subsequent inserts fail:
ERROR [stderr] (http--127.0.0.1-8080-1)
javax.persistence.TransactionRequiredException: JBAS011469:
Transaction is required to perform this operation (either use a
transaction or extended persistence context)
So my question is two fold
1) What on earth happened to my transaction midway through the process? Can it be avoided?
2) Is there a better approach to doing a bulk insert like this one (keeping in mind that i'm loading a bunch of Foo's and they need to be transformed into Bar's before persisting.
I'm running inside a jBoss 7.1.1.Final AS and hibernate-jpa-2.0-api
I have my ear-project deployed in jboss 5.1GA.
From webapp i don't have problem, the lookup of my ejb3 work fine!
es:
ShoppingCart sc= (ShoppingCart)
(new InitialContext()).lookup("idelivery-ear-1.0/ShoppingCartBean/remote");
also the iniection of my EntityManager work fine!
#PersistenceContext
private EntityManager manager;
From test enviroment (I use Eclipse) the lookup of the same ejb3 work fine!
but the lookup of entitymanager or PersistenceContext don't work!!!
my good test case:
public void testClient() {
Properties properties = new Properties();
properties.put("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");
properties.put("java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces");
properties.put("java.naming.provider.url","localhost");
Context context;
try{
context = new InitialContext(properties);
ShoppingCart cart = (ShoppingCart) context.lookup("idelivery-ear-1.0/ShoppingCartBean/remote"); // WORK FINE
} catch (Exception e) {
e.printStackTrace();
}
}
my bad test :
EntityManagerFactory emf = Persistence.createEntityManagerFactory("idelivery");
EntityManager em = emf.createEntityManager(); //test1
EntityManager em6 = (EntityManager) new InitialContext().lookup("java:comp/env/persistence/idelivery"); //test2
PersistenceContext em3 = (PersistenceContext)(new InitialContext()).lookup("idelivery/remote"); //test3
my persistence.xml
<persistence-unit name="idelivery" transaction-type="JTA">
<jta-data-source>java:ideliveryDS</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create-drop" /><!--validate | update | create | create-drop-->
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
</properties>
</persistence-unit>
my datasource:
<datasources>
<local-tx-datasource>
<jndi-name>ideliveryDS</jndi-name>
...
</local-tx-datasource>
</datasources>
I need EntityManager and PersistenceContext to test my query before build ejb...
Where is my mistake?
Server-side EntityManager cannot be serialized so that you can use it as a client side EntityManager. That would mean that EntityManager referenced on the client-side still can talk to the database, use connection pool, etc. It is impossible (think of firewall, which protects database server, for instance).
If you need to test JPA, use local EntityManager without JTA transactions. If you want to test EJBs you need to simulate whole EJB container. You can use Spring Pitchfork or Glassfish 3 embedded container (the latter option is easier).
I need to test JPA, use local EntityManager without JTA transactions!
I followed your suggestion:I created new persistence.xml with a new persistence-unit
<persistence-unit name="ideliveryTest" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>it.idelivery.model.Category</class>
<class>it.idelivery.model.User</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/application"/>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
<property name="hibernate.connection.username" value="root"/>
<property name="hibernate.connection.password" value=""/>
</properties>
</persistence-unit>
and in my test case:
try {
logger.info("Building JPA EntityManager for unit tests");
emFactory = Persistence.createEntityManagerFactory("ideliveryTest");
em = emFactory.createEntityManager();
} catch (Exception ex) {
ex.printStackTrace();
fail("Exception during JPA EntityManager instanciation.");
}
work fine!
In my maven project i put persistence.xml with persistence-unit type="RESOURCE_LOCAL" in src/test/resources
and i put persistence.xml with persistence-unit type="JTA" in src/main/resources
by this way I have two separates enviroment. One for test and one for production.
it's a best practice?