Eclipse & TomEE: no JPA logging - eclipse

I am working with Eclipse and TomEE 1.7.1.
If I have a problem with Exception logging of (Open)JPA:
Errors are not logged to console nor to logging file.
For example:
entityManager.createQuery("THIS IS NOT SQL");
If I run this in my WebApp it won't show anything into console.
BUT: If I set a Breakpoint and execute it manually (via Inspect Cntrl+Shift+I) the Exception is shown in console.
WTF is going on???
EDIT:
I have made a test-project with only three files, copied it into Tomee-Webapps-Folder started Tomee directly. Same result: nothing to see in console and no logfile was generated.
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
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">
<persistence-unit name="hprex">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/mytest"/>
<property name="javax.persistence.jdbc.user" value="user"/>
<property name="javax.persistence.jdbc.password" value="test"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<!-- <property name="openjpa.Log" value="DefaultLevel=TRACE, Runtime=TRACE, Tool=INFO, SQL=TRACE"/> -->
<!-- <property name="openjpa.ConnectionFactoryProperties" value="PrettyPrint=true, PrettyPrintLineLength=72, PrintParameters=true"/> -->
</properties>
</persistence-unit>
</persistence>
test.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</h:head>
<h:body>
<h:form>
<h:commandButton action="#{loginBean.login}"/>
</h:form>
</h:body>
</html>
LoginBean.java
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
#ManagedBean
#SessionScoped
public class LoginBean {
#PersistenceContext(unitName="mytest")
private EntityManager em;
public String login() {
Query query = em.createQuery("This is not SQL");
query.getResultList();
return "test";
}
}

I don't believe this path will result in anything being logged by the JPA provider. When OpenJPA can't create that query, it'll throw an exception back to your application.

what's your setup/config? By default exceptions are logged. You can check: catalina.out, catalina*.log and localhost*.log dependning the config you have for defaults locations (if you use log4j, slf4j...that's on your side to ensure it is logged).

Related

How to configure EJB/JPA in JTA transaction mode?

This is a simple guide for configuring JPA and connecting to your database using JTA transaction mode. Also it is including the most common mistakes that developers do and you should avoid them.
Hope this help you.
1- Set up a DataSource in your Application Server:
In order to configure JPA in your WebApp using JTA mode you need 1st setting up a DataSource. You can setup the DataSource from your Application Server (Glassfish / Payara / ...). but it is recommended to setup the Datasource through your Web App. Follow these steps to setup the DataSource for Glassfish or Payara through your Maven WebApp:
create a new folder (NOT Package) inside your project folder with name "setup".
create a new xml file and name it "glassfish-resources.xml" and save it inside "setup" folder.And write the bellow content:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
<resources>
<jdbc-resource enabled="true" jndi-name="**jdbc/DBDev01**" object-type="user" pool-name="**jdbc/DBDev01-ConnectionPool**">
<description/>
</jdbc-resource>
<jdbc-connection-pool allow-non-component-callers="false"
associate-with-thread="false" connection-creation-retry-attempts="0"
connection-creation-retry-interval-in-seconds="10"
connection-leak-reclaim="false"
connection-leak-timeout-in-seconds="0"
connection-validation-method="auto-commit"
datasource-classname="**org.mariadb.jdbc.MariaDbDataSource**"
fail-all-connections="false"
idle-timeout-in-seconds="300"
is-connection-validation-required="false"
is-isolation-level-guaranteed="true"
lazy-connection-association="false"
lazy-connection-enlistment="false"
match-connections="false"
max-connection-usage-count="0"
max-pool-size="32"
max-wait-time-in-millis="60000"
name="**jdbc/DBDev01-ConnectionPool**"
non-transactional-connections="false"
pool-resize-quantity="2"
res-type="javax.sql.DataSource" statement-timeout-in-seconds="-1" steady-pool-size="8" validate-atmost-once-period-in-seconds="0" wrap-jdbc-objects="false">
<!-- for MariaDB users, it recomended to add ?useMysqlMetadata=true, this will make MariaDB pretending that it is a MySQL for tools or libraries that not support MariaDB -->
<property name="URL" value="**jdbc:mariadb://XXX.XXX.XXX.XXX:XXXX/DB_NAME?useMysqlMetadata=true**"/>
<property name="User" value="**USERNAME**"/>
<property name="Password" value="**PASSWORD**"/>
</jdbc-connection-pool>
</resources>
Note: All values in between ** ** should be modified as per your settings.
This file will be loaded by your application server (Glassfish/Payara) after deploying your webapp. For Payara users you can also name the file with "payara-resources.xml" but with little modifications. Ref:Payara Deployment Descriptors.
2- Add Resource reference for the datasource in WEB-INF/web.xml:
you need to add a resource reference for the DataSource in your Webapp through adding this in WEB-INF/web.xml file:
<web-app .....>
......
<resource-ref>
<description>**DBDev01**</description>
<res-ref-name>**jdbc/DBDev01**</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<!-- <res-sharing-scope>Shareable</res-sharing-scope> -->
</resource-ref>
</web-app>
Note: The res-ref-name should match exactly the name you choose for the datasource in glassfish resources file.
3- Configure Persistence.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="**MyDB**" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<!-- List all Entity classes -->
<class>**com.MyEntityClassName**</class>
<jta-data-source>**jdbc/DBDev01**</jta-data-source>
<!-- you can list all entity classes you need and set this value to true. or set this value to false to include other entity clases -->
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<!-- while eclipselink not support MariaDB , set this property to enforce eclipselink to work with it as MySQL -->
<property name="eclipselink.target-database" value="MySQL"/>
</properties>
</persistence-unit>
</persistence>
Note 1: If you want to use JTA as transaction type, So you must defining jta-data-source. And it is a common mistake for developers adding DB URL,username and password in properties trying to connect to the database without defining the JTA data Source. This will not work and will lead your application server to use the default datasource that already defined which in common is an H2 database.
Note 2: eclipselink (JPA library) not supporting MariaDB. But there is a workarounds for that.
solution 1:: add "?useMysqlMetadata=true" as suffix on your connection URL Like: <property name="URL" value="**jdbc:mariadb://XXX.XXX.XXX.XXX:XXXX/DB_NAME?useMysqlMetadata=true"/> this will make MariaDB pretending that it is a MySQL.
solution 2: Enforce eclipselink to deal with the database as MySQL. this can be done by setting eclipselink.target-database property in persistence.xml as bellow:
<properties>
<!-- while eclipselink not support MariaDB , set this property to enforce eclipselink to work with it as MySQL -->
<property name="eclipselink.target-database" value="MySQL"/>
</properties>
4- Add JDBC client as Dependency in POM.xml:
<dependency>
<!-- This is for MariaDB. You should change it if you are using other kind of DB like MySQL or Oracle DB -->
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>2.7.2</version>
</dependency>
5- Enjoy with your Codes:
writing a sessionBean:
#Stateless
public class StudentManager
{
/* Notes:
1.you should use the same name exactly that defined in Persistence.xml file.
2.You can not use #PersistenceUnit with JTA. only use #PersistenceContext with JTA.
*/
#PersistenceContext(unitName="MyDB")
private EntityManager em;
public StudentManager()
{
}
public void persist(Student student) {
em.persist(student);
}
}
write TestController:
#Named
#SessionScoped
public class TestController
{
#Inject
private StudentManager studentManager;
private String message = "";
public void test()
{
Student student = new Student();
Student.setCode(11223344);
Student.setName("John");
studentManager.persist(Student);
/*Note:we used studentManager directly without constructing.
writing studentManager = new StudentManager() is a common mistake and will lead you to get a null EntityManager.*/
this.setMessage("A new Student already saved successful with Code:" + Student.getCode());
}
Common Question: Should use #Inject or #EJB? here is the answer
A simple JSF page for testing:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<h:form>
<h:commandButton value="Test Save a Student over JTA" action="#{testController.test()}" />
<br />
<h:outputLabel for="message" value="#{test.message}" />
</h:form>
</h:body>
</html>

Show logging parameter for (INSERT,UPDATE,SELECT) in EclipseLink JPA

I used logging in persistence.xml for EclipseLink JPA implementation, from
stackoverflow reference
but the parameters appears as ? how can i show them properly in my glassfish log output window.
The log level configuration is included in the definition of the persistence unit in the persistence.xml file, as follows:
The logging of SQL parameters can be enabled, or disabled through the following properties:
Disable:
Enable:
<property name="eclipselink.logging.level.sql" value="FINE"/>
<property name="eclipselink.logging.parameters" value="true"/>
full persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="ProjPU" transaction-type="JTA">
<jta-data-source>jdbc/POS</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="eclipselink.weaving" value="static" />
<property name="eclipselink.logging.level.sql" value="FINEST" />
<property name="eclipselink.logging.level" value="FINEST" />
<property name="eclipselink.logging.level.cache" value="FINEST" />
<property name="eclipselink.logging.parameters" value="true" />
</properties>
</persistence-unit>
</persistence>
Note: Setting eclipselink.logging.level to FINE is not sufficient (as of EclipseLink 2.4.0 - Juno), you have to set eclipselink.logging.level.sql to FINE.
This property will also control how parameters are logged in exceptions. By default parameters are only logged for log level < CONFIG.
Refernce:Documentation,Wiki Ecipse link

Openshift application and ejb "failed deployments ./ROOT.war

I'm developing a first application on openshift. Its a jsf application with database connectitivity.
First i tryed onli some jsf xhtml page without jpa and all works.
When i insert a bean to acces to the database i have the message from the server "failed deployments ./ROOT.waer. Precisely when I insert this code something goes wrong :
A class for view intents
#ManagedBean(name="utnavctrl" ,eager=true)
#SessionScoped
public class Utnavctrl {
boolean newrecord=false;
#EJB
private Usersdao usersdao;
public Utnavctrl(){
A bean class for db connection
#Stateless
#LocalBean
public class Usersdao {
#PersistenceContext(unitName = "primary")
private EntityManager em;
public Usersdao() {
// TODO Auto-generated constructor stub
}
public List<User> getAllUsers() {
return em.createNamedQuery("User.findAll", User.class)
.getResultList();
}
I can't understand why after adding these two class (without modifing the view side xhtml ecc) the program doesn't work anymore.
The persince.xml is
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
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">
<persistence-unit name="primary">
<!-- If you are running in a production environment, add a managed
data source, this example data source is just for development and testing! -->
<!-- The datasource is deployed as WEB-INF/kitchensink-quickstart-ds.xml, you
can find it in the source at src/main/webapp/WEB-INF/kitchensink-quickstart-ds.xml -->
<jta-data-source>java:jboss/datasources/MySQLDS</jta-data-source>
<class>com.antoiovi.gestcars.model.Automobili</class>
<class>com.antoiovi.gestcars.model.Group</class>
<class>com.antoiovi.gestcars.model.Prenotazioniauto</class>
<class>com.antoiovi.gestcars.model.Proglav</class>
<class>com.antoiovi.gestcars.model.Role</class>
<class>com.antoiovi.gestcars.model.User</class>
<class>com.antoiovi.gestcars.model.UserData</class>
<properties>
<!-- Properties for Hibernate -->
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.show_sql" value="false" />
</properties>
</persistence-unit>
</persistence>
Thhe bean.xml is
<?xml version="1.0" encoding="UTF-8"?>
<!-- This file can be an empty text file (0 bytes) -->
<!-- We're declaring the schema to save you time if you do have to configure
this in the future -->
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</bean
Can anybody help me?
Remove eager=true because this creates problems with OpenShift...I do not know why but I have seen.

Tomee with Arquillian using Postgres DB user lacks privilege or object not found

I have a problem when running arquillian tests against postgres db using tomee.
With all the info on the web I'm still struggling to get the problem solved.
javax.ejb.EJBException: The bean encountered a non-application exception; nested exception is:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLSyntaxErrorException: user lacks privilege or object not found: CREDENTIALS
Error Code: -5501
Call: SELECT ID, PASSWORD, USERNAME FROM credentials WHERE (USERNAME = ?)
bind => [phil]
The DB:
Name: registry
Table: credentials
Sits under manually created Schema: postgres
persistence.xml under directory src/main/resources
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" 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">
<persistence-unit name="registry" transaction-type="JTA">
<jta-data-source>RegistryDS</jta-data-source>
<non-jta-data-source>UnmanagedRegistryDS</non-jta-data-source>
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>za.co.registry.client.login.Credentials</class>
<properties>
<property name="eclipselink.debug" value="OFF"/>
<property name="eclipselink.weaving" value="static"/>
<property name="eclipselink.logging.level.sql" value="FINE"/>
<property name="eclipselink.logging.parameters" value="true"/>
<property name="eclipselink.logging.logger" value="DefaultLogger"/>
</properties>
</persistence-unit>
</persistence>
tomee.xml
<Resource id="RegistryDS" type="DataSource">
jdbcDriver=org.postgresql.Driver
jdbcUrl=jdbc:postgresql://127.0.0.1:5432/registry
userName=postgres
password=postgres
JtaManaged=true
</Resource>
<Resource id="UnmanagedRegistryDS" type="DataSource">
jdbcDriver=org.postgresql.Driver
jdbcUrl=jdbc:postgresql://127.0.0.1:5432/registry
userName=postgres
password=postgres
JtaManaged=false
</Resource>
pom.xml extract for arquillian tests
<dependency>
<groupId>org.apache.openejb</groupId>
<artifactId>arquillian-tomee-embedded</artifactId>
<version>1.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<version>1.0.3.Final</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
arquillian.xml extract
<container qualifier="tomee" default="true">
<configuration>
<property name="httpPort">-1</property>
<property name="stopPort">-1</property>
<property name="dir">target/apache-tomee-remote</property>
<property name="appWorkingDir">target/arquillian-test-working-dir</property>
<property name="properties" />
</configuration>
</container>
The ServiceTest.java file when loading the resources.
#Deployment
public static WebArchive createDeployment() {
WebArchive webArchive = newArchive();
webArchive.addClasses(Credentials.class);
webArchive.addAsResource("META-INF/persistence.xml");
webArchive.addAsResource("META-INF/beans.xml");
return webArchive;
}
And last the test findCredentialsByUsernameTest method in ServiceTest.java
#Test
public void findCredentialsByUsernameTest() {
Credentials login = LoginService.findByUsername("phil");
Assert.assertNotNull(login);
}
I do not start or end any EntityTransaction's in the test class.
It works injecting a EJB when the DB call in the service is removed.
What am I missing in the config or doing wrong for this not to be working?
Ok I think I know what I did wrong.
I need to run the tests against a embedded db.
The steps that I followed to get Arquillian tests to work against a embedded db;
Removed un-managed data source from tomee.xml, I added it because I wanted to use it for my tests. The other data source is still there because it is used when deploying to tomee to connect to postgres db.
<Resource id="UnmanagedRegistryDS" type="DataSource">
jdbcDriver=org.postgresql.Driver
jdbcUrl=jdbc:postgresql://127.0.0.1:5432/registry
userName=postgres
password=postgres
JtaManaged=false
</Resource>
I'm going to connect to HSQLDB.
HSQLDB (HyperSQL DataBase) is the leading SQL relational database software written in Java. It offers a small, fast multithreaded and transactional database engine with in-memory and disk-based tables and supports embedded and server modes
Next I create a second persistence.xml in src/test/resources called test-persistence.xml. Keep in mind the persistence-unit name testDatabase it is going to be used in the arquillian.xml file
<?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="test" transaction-type="JTA">
<jta-data-source>testDatabase</jta-data-source>
<class>za.co.registry.client.login.Credentials</class>
<properties>
<property name="openejb.jpa.init-entitymanager" value="true" />
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)" />
</properties>
</persistence-unit>
</persistence>
The arquillian.xml, I'm setting the testDatabase persistence unit properties in the file. See below under properties.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<arquillian
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
<container qualifier="openejb-embedded" default="true">
<configuration>
<property name="httpPort">-1</property>
<property name="stopPort">-1</property>
<property name="dir">target/apache-tomee-remote</property>
<property name="appWorkingDir">target/arquillian-test-working-dir</property>
<property name="properties">
testDatabase = new://Resource?type=DataSource
testDatabase.JdbcUrl = jdbc:hsqldb:mem:my-datasource
</property>
</configuration>
</container>
</arquillian>
Configuring my ServiceTest.java file to include the new persistence.xml file.
webArchive.addAsWebInfResource("META-INF/test-persistence.xml", "persistence.xml");
webArchive.addAsResource("META-INF/beans.xml");
Now I can run the findCredentialsByUsernameTest method.
#Test
public void findCredentialsByUsernameTest() {
//create credentials first
Credentials newCredentials = loginService.newCredentials(new Credentials("john", "password"));
//search for credentails
Credentials login = loginService.findByUsername("john");
Assert.assertNotNull(login);
Assert.assertEquals(newCredentials.getUsername(), login.getUsername());
}

Basic Standalone JPA example with Postgres using Eclipse

I have been trying to get a very basic standalone JPA example to work with Postgres using the Eclipse IDE.
I have a persistance.xml defined which looks like this.
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
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_1_0.xsd">
<persistence-unit name="sample" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>package.class</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="eclipselink.logging.level" value="INFO" />
<property name="eclipselink.jdbc.driver" value="org.postgresql.Driver" />
<property name="eclipselink.jdbc.url"
value="jdbc:postgresql://localhost:5432/sample" />
<property name="eclipselink.jdbc.user" value="scott" />
<property name="eclipselink.jdbc.password" value="tiger" />
</properties>
</persistence-unit>
</persistence>
This file lives in the src/main/resources/META-INF folder. I have included the src/main/resources folder to my source directory in eclipse. I have one simple Entity defined named User. When I try and create that entity
EntityManagerFactory entityManagerFactory
= Persistence.createEntityManagerFactory("sample");
EntityManager em = entityManagerFactory.createEntityManager();
EntityTransaction tx = em.getTransaction();
try {
User user = new User();
user.setEnabled(false);
user.setEmailId("test#test.com");
tx.begin();
em.persist(user);
tx.commit();
} catch (Exception e) {
em.getTransaction().rollback();
} finally {
em.close();
}
I get the following exception - Exception in thread "main" javax.persistence.PersistenceException: No Persistence provider for EntityManager named sample
It seems like my persistance.xml file is not being picked up. Where does the JPA framework look to load the persistance.xml file?
This was a dumb mistake. The file needs to called persistence.xml and not persistance.xml.