No autodetection of JPA Entities in maven-verify - java

If I put the persistence.xml in the src/test/META-INF folder, autodetection the Entities does not work with maven-verify. When the persistence.xml is located in the src/main/META-INF folder it works.
Running the tests in eclipse works in both cases.
Is there a way to get autodetection to work for maven-verify when the persistence.xml is located in the src/test Folder?
persistence.xml:
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name="Unit" transaction-type="RESOURCE_LOCAL">
<properties>
<!-- Scan for annotated classes and Hibernate mapping XML files -->
<property name="hibernate.archive.autodetection" value="class" />
</properties>
</persistence-unit>
</persistence>

By default autodetection works for entities in the same classpath item as persistence.xml. It can be configured by <jar-file> elements.
To enable correct autodetection when persistence.xml is in src/test/resources/META-INF I use the following trick:
persistence.xml:
<persistence ...>
<persistence-unit ...>
<jar-file>${project.build.outputDirectory}</jar-file>
...
</persistence-unit>
</persistence>
pom.xml - enable resource filtering for src/test/resources:
<project ...>
...
<build>
<testResources>
<testResource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
</testResource>
</testResources>
</build>
</project>
Though I'm not sure how to use it if your persistence.xml is actually in src/test/META-INF.

If you use Spring Framework you can do the following with a PersistenceUnitPostProcessor
CustomPersistenceUnitPostProcessor:
package com.yourpackage.utils.jpa.CustomPersistenceUnitPostProcessor;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.Entity;
import net.sourceforge.stripes.util.ResolverUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.orm.jpa.persistenceunit.MutablePersistenceUnitInfo;
import org.springframework.orm.jpa.persistenceunit.PersistenceUnitPostProcessor;
/**
* This PersistenceUnitPostProcessor is used to search given package list for JPA
* entities and add them as managed entities. By default the JPA engine searches
* for persistent classes only in the same class-path of the location of the
* persistence.xml file. When running unit tests the entities end up in test-classes
* folder which does not get scanned. To avoid specifying each entity in the persistence.xml
* file to scan, this post processor automatically adds the entities for you.
*
*/
public class CustomPersistenceUnitPostProcessor implements PersistenceUnitPostProcessor, InitializingBean {
private static final Logger log = LoggerFactory.getLogger(CustomPersistenceUnitPostProcessor.class);
/** the path of packages to search for persistent classes (e.g. org.springframework). Subpackages will be visited, too */
private List<String> packages;
/** the calculated list of additional persistent classes */
private Set<Class<? extends Object>> persistentClasses;
/**
* Looks for any persistent class in the class-path under the specified packages
*/
#Override
public void afterPropertiesSet() throws Exception {
if (packages == null || packages.isEmpty())
throw new IllegalArgumentException("packages property must be set");
log.debug("Looking for #Entity in " + packages);
persistentClasses = new HashSet<Class<? extends Object>>();
for (String p : packages) {
ResolverUtil<Object> resolver = new ResolverUtil<Object>();
ClassLoader cl = this.getClass().getClassLoader();
log.debug("Using classloader: " + cl);
resolver.setClassLoader(cl);
resolver.findAnnotated(Entity.class, p);
Set<Class<? extends Object>> classes = resolver.getClasses();
log.debug("Annotated classes: " + classes);
persistentClasses.addAll(classes);
}
if (persistentClasses.isEmpty())
throw new IllegalArgumentException("No class annotated with #Entity found in: " + packages);
}
/**
* Add all the persistent classes found to the PersistentUnit
*/
#Override
public void postProcessPersistenceUnitInfo(MutablePersistenceUnitInfo persistenceUnitInfo) {
for (Class<? extends Object> c : persistentClasses)
persistenceUnitInfo.addManagedClassName(c.getName());
}
public void setPackages(List<String> packages) {
this.packages = packages;
}
}
Spring Config:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="thePersistenceUnitName" />
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
<!-- reference to the XA datasource -->
<property name="dataSource" ref="theDataSource" />
<property name="persistenceUnitPostProcessors">
<list>
<!-- custom implementation to avoid xml entity class declarations -->
<bean class="com.yourpackage.utils.jpa.CustomPersistenceUnitPostProcessor">
<property name="packages">
<list value-type="java.lang.String">
<value>com.yourpackage.model</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
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_1_0.xsd"
version="1.0">
<persistence-unit name="thePersistenceUnitName" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.format_sql" value="false" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.use_sql_comments" value="false" />
<property name="hibernate.generate_ddl" value="false" />
<property name="hibernate.database_platform" value="org.hibernate.dialect.MySQLInnoDBDialect" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect" />
</persistence-unit>
</persistence>

Related

Ejb wont initialize entity manager

my english is not my native language so i am sorry in advanced for my poor english.
My project is working well when i manage the transaction with entity manager, entity factory and get transactions.
I want to use the ejb to handle the transactions for me.
I did every thing needed in order for it to work but the ejb wont initalized the entity manager and he will stay null.
i cant understand what i am doing wrong.
i have configured my persistance.xml with jta data source and did all the annotations needed but still cant get it to work.
what i try to create a query i get a null pointer exception and the entity manager is null.
I have been searching and looking for a solution but did not succeed.
I hope some one here can find the answer.
Thank you for you time!
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="swap" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:jboss/datasources/swap</jta-data-source>
<class>org.Roper.WebService.Model.User</class>
<class>org.Roper.WebService.Model.BaseEntity</class>
<class>org.Roper.WebService.Model.Person</class>
<class>org.Roper.WebService.Model.Admin</class>
<class>org.Roper.WebService.Model.BusinessOwner</class>
<class>org.Roper.WebService.Model.Business</class>
<class>org.Roper.WebService.Model.Product</class>
<class>org.Roper.WebService.Model.Category</class>
<class>org.Roper.WebService.Model.Tourist</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<!-- Hibernate properties -->
<property name="javax.persistence.jdbc.driver"
value="org.postgresql.Driver" /> <!-- DB Driver -->
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.connection.zeroDateTimeBehavior"
value="convertToNull" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.dialect"
value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="hibernate.transaction.jta.platform"
value="org.hibernate.service.jta.platform.internal.JBossStandAloneJtaPlatform" />
<!-- Database properties -->
<property name="javax.persistence.jdbc.url"
value="jdbc:postgresql://hidden/swap?useUnicode=yes&characterEncoding=UTF-8" /> <!-- BD Mane -->
<property name="javax.persistence.jdbc.user" value="hidden" /> <!-- DB User -->
<property name="javax.persistence.jdbc.password"
value="hidden" /> <!-- DB Password -->
</properties>
</persistence-unit>
</persistence>
This is the main class that call the ejb:
#Path("PersonService")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public class PersonResource {
private static final Logger logger = Logger.getLogger(PersonResource.class);
#EJB
PersonService personService = new PersonService();
#GET
#Path("/users")
public List<Person> getUsers(#BeanParam FilterBean fb)
{
logger.info("Getting all users.");
return personService.GetAllUsers();
}
}
this is the service class that call the entity managet:
#Stateless
#LocalBean
public class PersonService {
private static final Logger logger = Logger.getLogger(PersonService.class);
#PersistenceContext(unitName="swap")
public EntityManager em;
/**
*This function is querying the database selecting all the person entities.
*#return List of all the users from the database.
*/
public List<Person> GetAllUsers()
{
logger.debug("Starting to get all users.");
try {
try {
List<Person> users = em.createQuery("SELECT u FROM Person u").getResultList();
logger.info("Success, got all users.");
return new ArrayList<Person>(users);
}
catch(PersistenceException e)
{
if(e.getCause().getCause().getMessage().contains("ERROR: relation \"users\" does not exist"))
{
logger.info("No users in the database.");
}
else
{
logger.error("Error while getting users from the database, error: ", e);
}
}
}catch(Exception e)
{
logger.error("Cant get the users, error: ",e);
}
return null;
}
The datasource from the standalone-full.xml:
<subsystem xmlns="urn:jboss:domain:datasources:5.0">
<datasources>
<datasource jndi-name="java:jboss/datasources/swap" pool-name="swap" enabled="true" use-java-context="true">
<connection-url>jdbc:postgresql://127.0.0.1:5432/swap?useUnicode=yes&characterEncoding=UTF-8</connection-url>
<driver>org.postgresql</driver>
<security>
<user-name>postgres</user-name>
<password>postgres</password>
</security>
</datasource>
<drivers>
<driver name="org.postgresql" module="org.postgresql">
<driver-class>org.postgresql.Driver</driver-class>
<xa-datasource-class>org.postgresql.Driver</xa-datasource-class>
</driver>
</drivers>
</datasources>
</subsystem>
Following lines look suspicious:
#EJB
PersonService personService = new PersonService();
It should be either injected (so no = new PersonService();is needed) or created via constructor but that instance is not managed by any container and, as a consequence, no injection happens there and EntityManager em stays null.
Please update your code as follows:
#EJB
PersonService personService;
Beside that, Integrating JAX-RS with EJB Technology and CDI section of JavaEE 6 tutorial suggests that JAX-RS resources should be either EJBs themselves (so annotated with #Stateless or #Stateful) OR CDI beans (so annotated with #ApplicationScoped or #RequestScoped). I would suggest to add a #Stateless annotation on the PersonResource class itself.

Glassfish 4 - TransactionRequiredException using Hibernate and CDI #Transactional

I am getting the following exception:
javax.el.ELException: javax.persistence.TransactionRequiredException
at com.sun.el.parser.AstValue.invoke(AstValue.java:279)
at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
Caused by: javax.persistence.TransactionRequiredException
at com.sun.enterprise.container.common.impl.EntityManagerWrapper.doTxRequiredCheck(EntityManagerWrapper.java:161)
at com.sun.enterprise.container.common.impl.EntityManagerWrapper.doTransactionScopedTxCheck(EntityManagerWrapper.java:151)
at com.sun.enterprise.container.common.impl.EntityManagerWrapper.persist(EntityManagerWrapper.java:299)
I am using Hibernate 4.3.5
#Named
#SessionScoped
public class MenuBean implements Serializable {
#PersistenceContext
private EntityManager entityManager;
#Transactional
public void create() {
MenuTitle menu = new MenuTitle();
menu.setLabel(label);
entityManager.persist(menu); //exception in this line
label = null;
}
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://www.oracle.com/webfolder/technetwork/jsc/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="MyPersistenceUnit" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>MySQL5</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.current_session_context_class" value="jta"/>
<property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform"/>
<property name="hibernate.hbm2ddl.auto" value="none"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
</properties>
</persistence-unit>
I have also tried to set hibernate.transaction.jta.platform to org.hibernate.engine.transaction.jta.platform.internal.SunOneJtaPlatform but it results in the same error.
EJB CMT´s are working fine.
The Create action is called from a commandButton:
<p:commandButton value="Create" process="#this type" update=":megaMenuForm:mainMenu" actionListener="#{menuBean.create()}" oncomplete="closeMenuDialog(xhr, status, args)"/>
See EJB specs if you want to manage transaction. Inject a resource UserTransaction.
Also #Transactional with not do anything here since you are using EJB.
In general you example should work, and #Transactional annotation will be just ignored. Could you try to make an interface, and call create method through it?
Looks like you are using EJB 2 style coding, but Glassfish 4 implements EJB 3.1, so it is better to go with a new one.

Multiple persistance unit in persistence.xml creating tables in one another

I am using JPA (hibernate) and have the following persistence.xml
<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="DB1" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.dto1.AccessRight</class>
<class>com.dto1.Component</class>
<class>com.dto1.UserRight</class>
<properties>
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
<persistence-unit name="DB2" transaction-type="RESOURCE_LOCAL">
<class>com.dto2.Auditlog</class>
<properties>
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
</persistence>
In code i use the following to get EntityManager factory the following way:
private static final EntityManagerFactory emf_db1 = Persistence.createEntityManagerFactory(DB1_PU_NAME, getConnectionProps(DB1_PU_NAME));
private static final EntityManagerFactory emf_db2 = Persistence.createEntityManagerFactory(DB2_PU_NAME, getConnectionProps(DB2_PU_NAME));
private static Map<String, String> getConnectionProps(String pu) {
Map<String, String> dbConfProps = null;
dbConfProps = new HashMap<String, String>();
// Configure the Database properties
ConnectionEntity conn_en = ConnectionEntity.getConnectionEntity();
dbConfProps.put("hibernate.dialect", conn_en.getDbdialect());
if (pu.equals(DB2_PU_NAME)) {
dbConfProps.put("hibernate.connection.url", conn_en.getDB2_dburl());
} else {
dbConfProps.put("hibernate.connection.url", conn_en.getDB1_dburl());
}
dbConfProps.put("hibernate.connection.driver_class", conn_en.getDriver());
dbConfProps.put("hibernate.connection.username", conn_en.getUsername());
dbConfProps.put("hibernate.connection.password", conn_en.getPassword());
return dbConfProps;
}
public static javax.persistence.EntityManager getInstance(String persistanceUnit) {
logger.log("getInstance entered");
if (persistanceUnit.equalsIgnoreCase(DB1_PU_NAME)) {
return emf_idm.createEntityManager();
}
return emf_logs.createEntityManager();
}
Where conn_en has the dbConfiguration in a property file and reads from it. The thing what happens is that both database create each other tables on runtime whenever my application performs some task. During the execution i have to make entries in the tables of both databases. DB1 creates extra tables from DB2 and vice-versa. Any suggestion what is going wrong here?
Use <exclude-unlisted-classes>true</exclude-unlisted-classes> in both of your persistence units. As per this document entities that are not listed in particular persistence unit will not be managed by this unit!
Update: As per new specification for JPA 2 in jsr317
The set of managed persistence classes that are managed by a persistence unit is defined by using one or
more of the following:[81]
• Annotated managed persistence classes contained in the root of the
persistence unit (unless the exclude-unlisted-classes element is specified)
and with reference to that following is exclude-unlisted-classes xsd
<xsd:element name="exclude-unlisted-classes" type="xsd:boolean" default="true" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
When set to true then only listed classes and jars will
be scanned for persistent classes, otherwise the
enclosing jar or directory will also be scanned.
Not applicable to Java SE persistence units.
</xsd:documentation>
</xsd:annotation>
Default value of <exclude-unlisted-classes> has been changed to true if you are using JPA 2 for implementation one should use <exclude-unlisted-classes/> only instead of configuration specified above.

JPA No Persistence provider for EntityManager

I know there are some other questions on this subject, but none of the answers worked.
I am new to JPA and I am using EclipseLink as implementation and Eclipse as IDE.
This is my persistence.xml (it is in META-INF folder):
<?xml version="1.0" encoding="UTF-8" ?>
<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" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="DBService" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>com.maze.model.EventModel</class>
<class>com.maze.model.StoryModel</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/mazedb;create=true" />
<property name="javax.persistence.jdbc.user" value="user" />
<property name="javax.persistence.jdbc.password" value="pass" />
<!-- EclipseLink should create the database schema automatically -->
<property name="eclipselink.ddl-generation" value="create-tables" />
<property name="eclipselink.ddl-generation.output-mode" value="database" />
</properties>
</persistence-unit>
</persistence>
and here I am trying to get an EntityManagerFactory
private EntityManagerFactory emf;
emf = Persistence.createEntityManagerFactory("DBService");
At runtime, I get this error:
javax.persistence.PersistenceException: No Persistence provider for EntityManager named DBService
I have followed the steps from tutorials, but no results...
Edit: I have also added into WEB-INF/lib these jars: eclipselink.jar; javax.persistence_2.0.3.v201010191057.jar; mysql-connector-java-5.1.17-bin.jar, added JPA to the Project Facets but no have seen no results yet...
put your persistence.xml in the META-INF directory of your war file. Also, put a copy in your lib directory and the classes directory.
I am using eclipselink at work, using a standalone jar package that contains my entity classes, a MET-INF directory with the persistence.xml and it works fine.
Probably you need to make a jar file containing the entity classes, plus a MET-INF/persistence.xml, and add this jar file to your lib directory, alongside the eclipselink.jar.
The other thing to check is the RESOURCE-LOCAL, you should use this if you are using JPA in a web-app, with no entity beans components, or in a standalone application.
You must put your persistence.xml in the META-INF and write persistence.xml with Lowercase letter.
I think you wrote first letter or some letter with Capital letter and i have this error too.
You must write exactly like this: persistence.xml

JPA, Spring and ObjectDB not updating

I am quite a newbie to Spring JPA in cooperation with ObjectDB database, but I have encountered a problem that I cannot work out.
I have an application written with the mentioned technologies and it works OK, it persists new entities etc. (thus I think there is no problem with the configuration beans), except for updating even the simplest OneToMany/ManyToOne relations. Those updates are not persisted to the database and I cannot figure out why. Here's the snippet of my code:
Entity Team (1:N):
#Entity
public class Team implements Serializable {
...
List<Player> squad;
...
#OneToMany(mappedBy="team", cascade=CascadeType.PERSIST)
public List<Player> getSquad() {
return squad;
}
...
}
Entity Player (N:1)
#Entity
public class Player implements Serializable {
...
private Team team;
...
#ManyToOne
public Team getTeam() {
return team;
}
...
}
Here is a snippet from controller using both DAO objects and the problem:
public ModelAndView addPlayer(HttpServletRequest request, HttpServletResponse response) throws Exception {
...
Team t = teamDao.getTeamById(1); // retrieves an object with ID=1
Player p = playerDao.getPlayerById(1); // retrieves a player with ID=1
t.getSquad().add(p); // adds a player to the squad -> working fine but does not persist
System.out.println("Size of squad: " + t.getSquad().size()); // the player is there
...
return new ModelAndView("index.jsp", "team", t);
}
When I try to list all players in the team inside the index.jsp page or try to add another player the same way, the squad is always empty - nothing persisted to the database. Neither the team object, nor the player object. What do I do wrong?
Any help would be appreciated. Thanks.
EDIT: here is my 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="NewPU" transaction-type="RESOURCE_LOCAL">
<provider>com.objectdb.jpa.Provider</provider>
<properties>
<property name="javax.persistence.jdbc.url" value="C:/file.odb" />
<property name="javax.persistence.jdbc.user" value="admin"/>
<property name="javax.persistence.jdbc.password" value="admin"/>
</properties>
</persistence-unit>
P.S. The absolute path "C:/file.odb" is only for demonstration purposes.
and here is Spring configuration:
<mvc:annotation-driven />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="NewPU" />
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
CascadeType.PERSIST cascades the persistens of a new object but you load a player from the database and attach the player to your team. If you want to cascade that you have to add the CascadeType.MERGE
cascade = {CascadeType.PERSIST, CascadeType.MERGE}
You may have a look at CascadeType.ALL.

Categories

Resources