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?
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'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);
}
I have an empty persistenceUnit in my jar file:
<persistence-unit transaction-type="JTA" name="base1">
</persistence-unit>
<persistence-unit transaction-type="JTA" name="base2">
</persistence-unit>
My idea is to replace the empty persistenceUnit by a full persistenceUnit with properties and classes in my main project, like this:
<persistence-unit name="base1" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>java:jboss/datasources/myDS</jta-data-source>
<class>br.com.myproject.MyClass</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<shared-cache-mode>NONE</shared-cache-mode>
<properties>
<property name="hibernate.hbm2ddl.auto" value="none" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="false" />
<property name="hibernate.cache.use_second_level_cache"
value="false" />
</properties>
</persistence-unit>
But when i try to start server i got the following error:
Caused by: org.jboss.as.server.deployment.DeploymentUnitProcessingException: WFLYJPA0038: Falha ao adicionar o serviço da unidade de persistência para base1
Caused by: org.jboss.msc.service.DuplicateServiceException: Service jboss.persistenceunit.myproject#base1.__FIRST_PHASE__ is already registered"}}
Is there any way to override the persistenceUnit ?
If you really need to dynamically override your persistence.xml, this might be best done during building.
my personal warning: it sounds like a configuration-hell to me and I'd rather suggest using a container-managed JNDI approach here.
But anyway:
Use 2 maven profiles.
And if you activate profile1, then persistence.xml from profile1 will be added at the right place. and if you activate profile2 persistence.xml from profile2 will be taken.
therefore use the copy-resources-mojo for maven.
https://maven.apache.org/plugins/maven-resources-plugin/examples/copy-resources.html
If just the values of parameters change, and not the whole structure,
then you can also just "filter" and replace strings during maven-processes
then you would define properties in the profiles.
https://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html
You can also add a basic persistence.xml to your project as a default file. So if no maven-profile is activated, this one will be used. (even though it might happen, that the app doesn't work as expected, if the data-resource is not configured correctly)
Spring provides an interface JpaVendorAdapter which allows to plug in any JPA vendor specific configuration through Spring Java config or XML configuration during application startup.
You can create an EntityManagerFactory instance with LocalContainerEntityManagerFactoryBean and any implementation classes of JpaVendorAdapter such as HibernateJpaVendorAdapter, EclipseLinkJpaVendorAdapter or OpenJpaVendorAdapter.
I believe you don't even need to define the empty persistence unit in persistence.xml if your application used Spring.
Below is the sample on how to create EntityManagerFactory with Spring Java config:
#Inject
private DataSource base1DataSource;
#Inject
private DataSource base2DataSource;
#Bean
public EntityManagerFactory base1EntityManagerFactory()
throws IOException, NamingException {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
LocalContainerEntityManagerFactoryBean containerEntityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
containerEntityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
containerEntityManagerFactoryBean.setPackagesToScan("YOUR_PACKAGE_NAMES");
containerEntityManagerFactoryBean.setJtaDataSource(base1DataSource);
containerEntityManagerFactoryBean.setJpaProperties(loadBase1JpaProperties());
containerEntityManagerFactoryBean.setSharedCacheMode(SharedCacheMode.ENABLE_SELECTIVE);
containerEntityManagerFactoryBean.setPersistenceUnitName("base1");
containerEntityManagerFactoryBean.afterPropertiesSet();
return containerEntityManagerFactoryBean.getObject();
}
#Bean
public EntityManagerFactory base2EntityManagerFactory()
throws IOException, NamingException {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
LocalContainerEntityManagerFactoryBean containerEntityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
containerEntityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
containerEntityManagerFactoryBean.setPackagesToScan("YOUR_PACKAGE_NAMES");
containerEntityManagerFactoryBean.setJtaDataSource(base2DataSource);
containerEntityManagerFactoryBean.setJpaProperties(loadBase2JpaProperties());
containerEntityManagerFactoryBean.setSharedCacheMode(SharedCacheMode.ENABLE_SELECTIVE);
containerEntityManagerFactoryBean.setPersistenceUnitName("base2");
containerEntityManagerFactoryBean.afterPropertiesSet();
return containerEntityManagerFactoryBean.getObject();
}
#Bean
public Properties loadBase1JpaProperties() throws IOException {
ClassPathResource resource = new ClassPathResource("base1-persistence.properties");
return PropertiesLoaderUtils.loadProperties(resource);
}
#Bean
public Properties loadBase2JpaProperties() throws IOException {
ClassPathResource resource = new ClassPathResource("base2-persistence.properties");
return PropertiesLoaderUtils.loadProperties(resource);
}
Please refer to the following URL for additional info on what you can override to your persistence.xml :
http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.html
I assume you want to declare your persistent unit in a superclass and you want to define the persistent unit in a explicit project. If true you could use a JNDI approch like this:
<persistence-unit name="MyPersistenceUnit"
transaction-type="JTA">
<jta-data-source>java:/myDS</jta-data-source>
<mapping-file>META-INF/orm.xml</mapping-file>
<jar-file>Persistence.jar</jar-file>
<properties>
<property name="jboss.entity.manager.jndi.name" value="java:app/applicationEntitymanager"/>
<!-- Properties for Hibernate -->
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="hibernate.show_sql" value="false" />
</properties>
</persistence-unit>
on the other side you can acces the Entitymanager with:
#Resource(mappedName = "java:app/applicationEntitymanager")
protected EntityManager em;
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.
Persistence units in persistence.xml are created during building the application. As I want to change the database url at runtime, is there any way to modify the persistence unit at runtime? I supposed to use different database other than pre-binded one after distributed.
I'm using EclipseLink (JPA 2.1)
Keep the persistence unit file (Persistence.xml) as it's. You can override the properties in it as follows.
EntityManagerFactory managerFactory = null;
Map<String, String> persistenceMap = new HashMap<String, String>();
persistenceMap.put("javax.persistence.jdbc.url", "<url>");
persistenceMap.put("javax.persistence.jdbc.user", "<username>");
persistenceMap.put("javax.persistence.jdbc.password", "<password>");
persistenceMap.put("javax.persistence.jdbc.driver", "<driver>");
managerFactory = Persistence.createEntityManagerFactory("<current persistence unit>", persistenceMap);
manager = managerFactory.createEntityManager();
You can use Persistence.createEntityManagerFactory(Map) to pass properties to choose the database URL and other settings.
In Long-lived Session Architecture you should create a Plug-in-Framework.
Therefore you need to create a different Thread-Group and Class-Repository.
This might be your Class-Loader-Tree
System-Class-Loader (usually a URLClassLoader, contains the Entitys)
JPA-Class-Loader
Load your jpa.jar with persistence.xml inside, specify the Database-Configuration from Application-Class-Loader
Instanciate your entityManager/session-factory.
Load any plugin you need to work with the DataBase. Execute Unit-Tests (;D) and Plugin-Integration-Tests.
If you are using Thorntail framework, you can wire-up the persistence.xml file to fetch runtime variables from "project-defaults.yml" file.
<persistence-unit name="java:jboss/datasources/my-postgres-ds">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.package.jpa.EntityClass1</class>
<class>com.package.jpa.EntityClass2</class>
<class>com.package.jpa.EntityClass3</class>
<properties>
<property name="hibernate.archive.autodetection" value="class"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
<property name="hibernate.connection.url"
value="${thorntail.datasources.data-sources.my-postgres-ds.connection-url}"/>
<property name="hibernate.connection.username"
value="${thorntail.datasources.data-sources.my-postgres-ds.user-name}"/>
<property name="hibernate.connection.password"
value="${thorntail.datasources.data-sources.my-postgres-ds.password}"/>
<property name="hibernate.default_schema" value="public"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
Take note of the dynamic DB values in ${...} as the point to values in the project-default.yml file.
Then you project-defaults.yml file will have an entry like this:
thorntail:
http:
port: 8989
datasources:
data-sources:
my-postgres-ds:
driver-name: my-postgres-driver
connection-url: "jdbc:postgresql://localhost:5432/my-db-name"
user-name: my-user-name
password: "my-password#"
jdbc-drivers:
my-postgres-driver:
driver-module-name: org.postgresql
driver-xa-datasource-class-name: org.postgresql.xa.PGXADataSource
I expect this should also work for Spring boot using application.properties and persistence.xml