Having trouble getting JPA to work on Wildfly 19.1 - jpa

I am fairly new to Wildfly and really new to JPA. I get a null exception when I try to call a method from the DAO. I made some changes suggested using the #Stateless and #Inject annotations, but the DAO does not appear to be initializing at all. The object is null when I try to call the findAllClientCompanies method.
Here is the peristence.xml file.
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="miscPU">
<jta-data-source>java:/jdbc/misc</jta-data-source>
<properties>
<property name="hibernate.show_sql" value="false"/>
<property name="hibernate.transaction.flush_before_completion" value="true"/>
</properties>
</persistence-unit>
<persistence-unit name="autojobsPU">
<jta-data-source>java:/jdbc/autojobs</jta-data-source>
<properties>
<property name="hibernate.show_sql" value="false"/>
<property name="hibernate.transaction.flush_before_completion" value="true"/>
</properties>
</persistence-unit>
</persistence>
Here is the entity declaration:
#Entity
#Table(name="clientcompany")
public class ClientCompany extends Company implements Serializable {
Here is the dao, the findAllClientCompanies is the specific method that is blowing up with a null exception:
package com.lingosys.jpa;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.Query;
import java.io.Serializable;
import java.util.List;
/**
*
* #author mphoenix
*/
#Stateless
public class ClientCompanyDAO implements Serializable {
#PersistenceContext(unitName="miscPU")
private EntityManager em;
public ClientCompanyDAO() {
}
public void create(ClientCompany clientCompany) {
em.persist(clientCompany);
}
public EntityTransaction getTransaction() {
return em.getTransaction();
}
public ClientCompany findClientCompany(int id) {
ClientCompany clientCompany = (ClientCompany) em.find(ClientCompany.class, id);
return clientCompany;
}
public List <ClientCompany> findAllClientCompanies() {
TypedQuery<ClientCompany> query = em.createQuery("select c from ClientCompany c", ClientCompany.class);
return query.getResultList();
}
public void delete(ClientCompany clientCompany) {
em.remove(em.contains(clientCompany) ? clientCompany:em.merge(clientCompany));
}
public int deleteAllClientCompanies() {
Query query = em.createQuery("delete from ClientCompany");
return query.executeUpdate();
}
}
And here is the JSF bean that calls the dao method:
#Inject
private ClientCompanyDAO daoClientCompany;
private boolean noValidEmail = false;
private String fakeEmailUserName = "";
private Connection conn;
private List<ClientCompany> unsortedList;
private String specialInstructions;
private String createdBy;
//XML processing variables
private Document document = null;
private String xmlMsgs = "";
private boolean xmlLoaderDisabled = false;
//prospect handling variables
private boolean prospectDisabled = false;
private static final String YES = "Yes";
//Legal entity based variables
boolean entitySet = false;
boolean lls = false;
boolean clientIDSet = false;
boolean billingInstructionsSet = false;
boolean billingEmailSet = false;
private static final String[] IS_LLS = {"LLS", "Coto/TI", "LLS-UK"};
boolean companyLoggedOn = false;
private boolean processDisabled = true;
private boolean userSpecificEntity = false;
/**
* Constructor initializes Web Service client, Hibernate DAOs, UI lists, and
* client view.
*
*/
public ClientCreatorBean() {
fmrws = new FormerWSOps();
try {
unsortedList = daoClientCompany.findAllClientCompanies();
view = fmrws.getClientCompanyView();
} catch (Exception ex) {
java.util.logging.Logger.getLogger(ClientCreatorBean.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
reset();

OK it looks like this problem had to do with my invoking the DAO in my constructor. I resolved it by putting the code in another method and prefacing that method with the #PostConstructor annotation.

Related

AttributeConverter not working in EclipseLink, works fine in Hibernate

I wanted to try a simple test case with a converter. Unfortunately it doesn't work with payara 5. It works fine with Wildfly 20.0.1. Database is H2.
pom.xml
<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<modelVersion>4.0.0</modelVersion>
<groupId>fjp</groupId>
<artifactId>converter</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<failOnMissingWebXml>false</failOnMissingWebXml>
</properties>
<dependencies>
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-api</artifactId>
<version>8.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2"
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_2.xsd"
>
<persistence-unit name="primary" transaction-type="JTA">
<!--jta-data-source>java:/TestDS</jta-data-source-->
<jta-data-source>jdbc/TestDS</jta-data-source>
<class>fjp.converter.entity.Employee</class>
<class>fjp.converter.entity.converter.StatusConverter</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create" />
<property name="eclipselink.logging.level.sql" value="FINE"/>
<property name="eclipselink.logging.parameters" value="true"/>
<property name="hibernate.show_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>
DAO :
package fjp.converter.dao;
import java.util.List;
import fjp.converter.entity.Employee;
public interface EmployeeDAO {
public Employee find(long i);
public void create(Employee e);
public void delete(Employee e);
public void delete(long i);
public List<Employee> findByStatus(Employee.Status status);
}
DAOImpl
package fjp.converter.dao;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.PersistenceContext;
import javax.persistence.EntityManager;
import fjp.converter.entity.Employee;
#Stateless
public class EmployeeDAOImpl implements EmployeeDAO {
#PersistenceContext
private EntityManager em;
public Employee find(long i) {
return em.find(Employee.class, i);
}
#Override
public void create(Employee e) {
em.persist(e);
}
#Override
public void delete(long i) {
var e = this.find(i);
if(e != null) em.remove(e);
}
#Override
public void delete(Employee e) {
if(e == null) return;
delete(e.getId());
}
#Override
public List<Employee> findByStatus(Employee.Status status) {
return em.createNamedQuery("Employee.findByStatus", Employee.class)
.setParameter("status", status)
.getResultList();
}
}
Entity :
package fjp.converter.entity;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.AttributeConverter;
import javax.persistence.Convert;
import javax.persistence.NamedQuery;
import java.io.Serializable;
#NamedQuery(name="Employee.findByStatus", query="select e from Employee e where e.status=:status")
#Entity
public class Employee implements Serializable{
public enum Status {
SENIOR("SENIOR"),
JUNIOR("JUNIOR");
private String code;
private Status(String s) {
this.code = s;
}
public String getCode() {
return this.code;
}
}
#Id
private long id;
#Convert(converter = fjp.converter.entity.converter.StatusConverter.class)
private Status status;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Status getStatus() {
return this.status;
}
public void setStatus(Status s) {
this.status = s;
}
#Override
public String toString() {
return String.format("id=%d, status=%s", id, status == null ? null : status.getCode());
}
}
Converter :
package fjp.converter.entity.converter;
import javax.persistence.Converter;
import javax.persistence.AttributeConverter;
import fjp.converter.entity.Employee.Status;
#Converter
public class StatusConverter implements AttributeConverter<Status, String> {
#Override
public String convertToDatabaseColumn(Status e) {
return e == null ? null : e.getCode();
}
#Override
public Status convertToEntityAttribute(String s) {
if(s == null) return null;
switch(s) {
case "SENIOR": return Status.SENIOR;
case "JUNIOR": return Status.JUNIOR;
default: return null;
}
}
}
Servlet
package fjp.converter.servlet;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServlet;
import fjp.converter.dao.EmployeeDAO;
import fjp.converter.entity.Employee;
import fjp.converter.entity.Employee.Status;
import javax.inject.Inject;
#WebServlet("/test")
public class Test extends HttpServlet {
#Inject
private EmployeeDAO dao;
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
Employee e = new Employee();
long id = 1;
dao.delete(id);
e.setId(id);
e.setStatus(Status.SENIOR);
dao.create(e);
id = 2;
dao.delete(id);
e.setId(id);
e.setStatus(Status.JUNIOR);
dao.create(e);
Status status = Status.SENIOR;
var list = dao.findByStatus(status);
for(var o : list) {
System.out.println(o);
if(o.getStatus() != status) {
System.out.println("ERROR !!!!!");
}
}
status = Status.JUNIOR;
list = dao.findByStatus(status);
for(var o : list) {
System.out.println(o);
if(o.getStatus() != status) {
System.out.println("ERROR !!!!!");
}
}
}
}
First time you ask the servlet you get the error message :
[2021-05-13T19:08:07.512+0200] [Payara 5.2021.3] [PRÉCIS] [] [org.eclipse.persistence.session./file:/home/frederic/payara5/glassfish/domains/domain1/applications/converter-1.0/WEB-INF/classes/_primary.sql] [tid: _ThreadID=76 _ThreadName=http-thread-pool::http-listener-1(5)] [timeMillis: 1620925687512] [levelValue: 500] [[
SELECT ID, STATUS FROM EMPLOYEE WHERE (STATUS = ?)
bind => [SENIOR]]]
[2021-05-13T19:08:07.514+0200] [Payara 5.2021.3] [INFOS] [] [] [tid: _ThreadID=76 _ThreadName=http-thread-pool::http-listener-1(5)] [timeMillis: 1620925687514] [levelValue: 800] [[
id=2, status=JUNIOR]]
[2021-05-13T19:08:07.514+0200] [Payara 5.2021.3] [INFOS] [] [] [tid: _ThreadID=76 _ThreadName=http-thread-pool::http-listener-1(5)] [timeMillis: 1620925687514] [levelValue: 800] [[
ERROR !!!!!]]
If you refresh the page : it blows !
Local Exception Stack:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.7.7.payara-p3): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.h2.jdbc.JdbcSQLException: Violation dindex unique ou clé primaire: {0}
Unique index or primary key violation: {0}; SQL statement:
INSERT INTO EMPLOYEE (ID, STATUS) VALUES (?, ?) [23505-197]
The problem is you are editing an object after you call persist on it in ways not allowed by the JPA specification. What is happening here is you first create Employee e and set its ID and status (1, SENIOR), and call persist on this instance.
You then change the id and status values on e (2, JUNIOR) and again call persist on that same instance. Instance E though is already persisted, so this is ignored. When you query for status SENIOR, EclipseLink will query and find a row matching (1, SENIOR), but when it goes to the cache to look to see if it already has the data, it'll find your 'e' instance and so just return that. Your application logs an error because you've change the state of e to JUNIOR.
For proof of what is happening - try listing out what is in the database.
The solution is just to create a second Employee instance to represent the (2,JUNIOR) data.
Some differences in JPA providers are that EclipseLink will maintain 1st and 2nd level caches by default. This interferes with this situation because you are modifying objects in ways not allowed within the JPA spec, and EclipseLink remembers the data for longer than if there wasn't a cache. You are not allowed to modify primary keys within JPA.
It works if I add to persistence.xml :
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
So you can reuse the Employe but beware of second level cache.

EntityManager is null. Using JAX-RS and JPA on WAS-Liberty

I have just started learning JAX-RS and am trying to modify some examples from the O'Reilly RESTful Java with JAX-RS book. I've run into an issue where I am getting a null pointer exception when I try and POST an XML file to one of my JAX-RS services. The specific resource I am posting to uses JPA to persist information to a derby database. After reading several other question/responses and tutorials I am convinced my code is correct but perhaps I am missing some configuration. It seems the entity manager isn't being injected for some reason even though I have the appropriate annotations. Any input on my issue would be appreciated. Please see the following excerpts of my project that I think will be useful:
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="jpa-example" transaction-type="JTA">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<jta-data-source>java:comp/env/jdbc/DerbyConnection</jta-data-source>
<class>com.example.persistence.UserEntity</class>
<class>com.example.persistence.SearchEntity</class>
<properties>
<property name="openjpa.TransactionMode" value="managed"/>
<property name="openjpa.ConnectionFactoryMode" value="managed"/>
<property name="openjpa.LockTimeout" value="30000"/>
<property name="openjpa.jdbc.TransactionIsolation" value="read-committed"/>
<property name="openjpa.Log" value="TRACE"/>
<property name="openjpa.jdbc.UpdateManager" value="operation-order"/>
</properties>
</persistence-unit>
</persistence>
server.xml
<server description="new server">
<!-- Enable features -->
<featureManager>
<feature>jsp-2.2</feature>
<feature>jdbc-4.0</feature>
<feature>jpa-2.0</feature>
<feature>localConnector-1.0</feature>
<feature>jaxrs-1.1</feature>
<feature>ejbLite-3.1</feature>
</featureManager>
<httpEndpoint host="localhost" httpPort="9080" httpsPort="9443" id="defaultHttpEndpoint"/>
<jdbcDriver id="derbyJDBCDriver">
<library name="DerbyLib">
<fileset dir="/Users/jackson/Documents/db-derby-10.10.1.1-bin/lib" includes="derby.jar"/>
</library>
</jdbcDriver>
<dataSource id="DerbyConnection" jdbcDriverRef="derbyJDBCDriver" jndiName="jdbc/DerbyConnection">
<properties.derby.embedded createDatabase="create" databaseName="example"/>
</dataSource>
<applicationMonitor updateTrigger="mbean"/>
<webApplication id="REST" location="REST.war" name="REST"/>
</server>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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/web-app_3_0.xsd" version="3.0">
<display-name>REST</display-name>
<servlet>
<description>
JAX-RS Tools Generated - Do not modify</description>
<servlet-name>JAX-RS Servlet</servlet-name>
<servlet-class>com.ibm.websphere.jaxrs.server.IBMRestServlet</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.example.services.RESTConfig</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<enabled>true</enabled>
<async-supported>false</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>JAX-RS Servlet</servlet-name>
<url-pattern>
/rest/*</url-pattern>
</servlet-mapping>
<ejb-local-ref>
<ejb-ref-name>ejb/UserResource</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local>com.example.services.UserResource</local>
<ejb-link>
com.example.services.UserResourceBean
</ejb-link>
</ejb-local-ref>
</web-app>
RESTConfig.java
package com.example.services;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
public class RESTConfig extends Application {
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<Class<?>>();
classes.add(HelloWorld.class);
classes.add(UserResourceBean.class);
return classes;
}
}
UserEntity.java
package com.example.persistence;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
#Entity(name = "User")
public class UserEntity {
private long id;
private String login;
private String password;
private String firstName;
private String lastName;
private String email;
private String role;
private String status;
#Id
#GeneratedValue
public long getId()
{
return id;
}
public void setId(long id)
{
this.id = id;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
#Override
public String toString()
{
return "UserEntity {" +
"id=" + id +
", email='" + email + '\'' +
", password='" + password + '\'' +
", firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", email='" + email + '\'' +
", role='" + role + '\'' +
", status='" + status + '\'' +
'}';
}
}
UserResource.java
package com.example.services;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import com.example.domain.User;
import com.example.domain.Users;
#Path("/users")
public interface UserResource
{
#POST
#Consumes("application/xml")
Response createUser(User user, #Context UriInfo uriInfo);
#GET
#Produces("application/xml")
//#Formatted
Users getUsers(#QueryParam("start") int start,
#QueryParam("size") #DefaultValue("10") int size,
#QueryParam("firstName") String firstName,
#QueryParam("lastName") String lastName,
#Context UriInfo uriInfo);
#GET
#Path("{id}")
#Produces("application/xml")
User getUser(#PathParam("id") long id);
}
UserResourceBean.java
package com.example.services;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import com.example.domain.Link;
import com.example.domain.User;
import com.example.domain.Users;
import com.example.persistence.UserEntity;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
#Stateless
public class UserResourceBean implements UserResource
{
#PersistenceContext(unitName="jpa-example")
private EntityManager em;
public Response createUser(User user, UriInfo uriInfo)
{
UserEntity entity = new UserEntity();
domain2entity(entity, user);
System.out.println(entity);
em.persist(entity);
em.flush();
System.out.println("Created user " + entity.getId());
UriBuilder builder = uriInfo.getAbsolutePathBuilder();
builder.path(Long.toString(entity.getId()));
return Response.created(builder.build()).build();
}
public User getUser(long id)
{
UserEntity user = em.getReference(UserEntity.class, id);
return entity2domain(user);
}
public static void domain2entity(UserEntity entity, User user)
{
entity.setId(user.getId());
entity.setLogin(user.getLogin());
entity.setPassword(user.getPassword());
entity.setFirstName(user.getFirstName());
entity.setLastName(user.getLastName());
entity.setEmail(user.getEmail());
entity.setRole(user.getRole());
entity.setStatus(user.getStatus());
}
public static User entity2domain(UserEntity entity)
{
User u = new User();
u.setId(entity.getId());
u.setLogin(entity.getLogin());
u.setPassword(entity.getPassword());
u.setFirstName(entity.getFirstName());
u.setLastName(entity.getLastName());
u.setEmail(entity.getEmail());
u.setRole(entity.getRole());
u.setStatus(entity.getStatus());
return u;
}
public Users getUsers(int start,
int size,
String firstName,
String lastName,
UriInfo uriInfo)
{
UriBuilder builder = uriInfo.getAbsolutePathBuilder();
builder.queryParam("start", "{start}");
builder.queryParam("size", "{size}");
ArrayList<User> list = new ArrayList<User>();
ArrayList<Link> links = new ArrayList<Link>();
Query query = null;
if (firstName != null && lastName != null)
{
query = em.createQuery("select u from Users u where u.firstName=:first and u.lastName=:last");
query.setParameter("first", firstName);
query.setParameter("last", lastName);
}
else if (lastName != null)
{
query = em.createQuery("select u from Users u where u.lastName=:last");
query.setParameter("last", lastName);
}
else
{
query = em.createQuery("select u from Users u");
}
List userEntities = query.setFirstResult(start)
.setMaxResults(size)
.getResultList();
for (Object obj : userEntities)
{
UserEntity entity = (UserEntity) obj;
list.add(entity2domain(entity));
}
// next link
// If the size returned is equal then assume there is a next
if (userEntities.size() == size)
{
int next = start + size;
URI nextUri = builder.clone().build(next, size);
Link nextLink = new Link("next", nextUri.toString(), "application/xml");
links.add(nextLink);
}
// previous link
if (start > 0)
{
int previous = start - size;
if (previous < 0) previous = 0;
URI previousUri = builder.clone().build(previous, size);
Link previousLink = new Link("previous", previousUri.toString(), "application/xml");
links.add(previousLink);
}
Users users = new Users();
users.setUsers(list);
users.setLinks(links);
return users;
}
}
It is in this last file in which the NPE occurs. Specifically in function createUser, the following code throws a NPE: em.persist(entity);
I solved the injection issue by altering the code in RESTconfig.java to appear as follows:
package com.example.services;
import java.util.HashSet;
import java.util.Set;
import javax.naming.InitialContext;
import javax.ws.rs.core.Application;
public class RESTConfig extends Application {
public Set<Object> getSingletons()
{
HashSet<Object> set = new HashSet();
try
{
InitialContext ctx = new InitialContext();
obj = ctx.lookup(
"java:comp/env/ejb/UserResource");
set.add(obj);
}
catch (Exception ex)
{
throw new RuntimeException(ex);
}
return set;
}
}

JPA java.lang.IllegalArgumentException: Object: [ id=XYZ ] is not a known entity type

I am faceing the following problem:
when i run my programme i get the following exceptions:
java.lang.IllegalArgumentException: Object: dviaufgabe1.MeinArtikel[
id=25 ] is not a known entity type. at
org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectForPersist(UnitOfWorkImpl.java:4128)
at
org.eclipse.persistence.internal.jpa.EntityManagerImpl.persist(EntityManagerImpl.java:406)
at dviaufgabe1.DVIAufgabe1.persist(DVIAufgabe1.java:78) at
dviaufgabe1.DVIAufgabe1.erstelleBasisDaten(DVIAufgabe1.java:55) at
dviaufgabe1.DVIAufgabe1.main(DVIAufgabe1.java:22)
or (for auto gen keys)
java.lang.IllegalArgumentException: Object: dviaufgabe1.MeinArtikel[
id=null ] is not a known entity type. at
org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectForPersist(UnitOfWorkImpl.java:4128)
at
org.eclipse.persistence.internal.jpa.EntityManagerImpl.persist(EntityManagerImpl.java:406)
at dviaufgabe1.DVIAufgabe1.persist(DVIAufgabe1.java:78) at
dviaufgabe1.DVIAufgabe1.erstelleBasisDaten(DVIAufgabe1.java:56) at
dviaufgabe1.DVIAufgabe1.main(DVIAufgabe1.java:22)
MeinArtikel.java
#Entity
public class MeinArtikel implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long artikelNummer;
private String name;
private String beschreibung;
private long preis;
private long lagerbestand;
public Long getArtikelNummer() {
return artikelNummer;
}
public String getBeschreibung() {
return beschreibung;
}
public long getLagerbestand() {
return lagerbestand;
}
public String getName() {
return name;
}
public long getPreis() {
return preis;
}
public void setBeschreibung(String beschreibung) {
this.beschreibung = beschreibung;
}
public void setLagerbestand(long lagerbestand) {
this.lagerbestand = lagerbestand;
}
public void setName(String name) {
this.name = name;
}
public void setPreis(long preis) {
this.preis = preis;
}
public void setArtikelNummer(Long id) {
this.artikelNummer = id;
}
#Override
public int hashCode() {
int hash = 0;
hash += (artikelNummer != null ? artikelNummer.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the artikelNummer fields are not set
if (!(object instanceof MeinArtikel)) {
return false;
}
MeinArtikel other = (MeinArtikel) object;
if ((this.artikelNummer == null && other.artikelNummer != null) || (this.artikelNummer != null && !this.artikelNummer.equals(other.artikelNummer))) {
return false;
}
return true;
}
#Override
public String toString() {
return "dviaufgabe1.MeinArtikel[ id=" + artikelNummer + " ]";
}
main class:
public class DVIAufgabe1 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
erstelleBasisDaten();
}
public static void erstelleBasisDaten() {
MeinArtikel a1 = new MeinArtikel();
// a1.setArtikelNummer(23L);
a1.setName("Bachelor of Science - Informatik (WH)");
a1.setBeschreibung("Informatik Bachelor der Westfälischen Hochschule");
a1.setPreis(0L);
a1.setLagerbestand(100L);
MeinArtikel a2 = new MeinArtikel();
// a2.setArtikelNummer(24L);
a2.setName("Master of Science - Informatik (WH)");
a2.setBeschreibung("Informatik Master der Westfälischen Hochschule");
a2.setPreis(100L);
a2.setLagerbestand(50L);
MeinArtikel a3 = new MeinArtikel();
// a3.setArtikelNummer(25L);
a3.setName("Master of Science - Informatik (TU München)");
a3.setBeschreibung("Informatik Master der TU München");
a3.setPreis(10000L);
a3.setLagerbestand(5L);
MeinArtikel a4 = new MeinArtikel();
// a4.setArtikelNummer(26L);
a4.setName("Abitur NRW");
a4.setBeschreibung("Abitur der Klasse 13");
a4.setPreis(1000L);
a4.setLagerbestand(500L);
persist(a1);
persist(a2);
persist(a3);
persist(a4);
}
public static void persist(Object object) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("DVIAufgabe1PU");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
try {
em.persist(object);
em.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
em.getTransaction().rollback();
} finally {
em.close();
}
}
persictence.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="DVIAufgabe1PU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>dviaufgabe1. MeinArtikel</class>
<class>dviaufgabe1.MeineKategorie</class>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:derby://localhost:1527/DVIAufgabe1"/>
<property name="javax.persistence.jdbc.password" value="myuser"/>
<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver"/>
<property name="javax.persistence.jdbc.user" value="myuser"/>
<property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
</properties>
</persistence-unit>
</persistence>
Firstly, you should delete the space in the persistence.xml, right before "MeinArtikel" in the first tag class. Then after
<class>dviaufgabe1.MeineKategorie</class>
add this line
<exclude-unlisted-classes>false</exclude-unlisted-classes>
you are missing a space in the persistence.xml, right before "MeinArtikel"

Hibernate: How configure EntityManager in Hibernate?

I create a hibernate project with 'hibernate tools'provide by JBoss to Eclipse.
Generated the Entities (POJO's) and then the DAO's.
This way for example:
#Entity
#Table(name = "area", catalog = "project_schema", uniqueConstraints = #UniqueConstraint(columnNames = "area"))
public class Area implements java.io.Serializable {
private Integer id;
private String area;
public Area() {
}
public Area(String area) {
this.area = area;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
#Column(name = "area", unique = true, nullable = false, length = 45)
public String getArea() {
return this.area;
}
public void setArea(String area) {
this.area = area;
}
}
And then the respectely DAO class (generated by Hibernate Tools too):
#Stateless
public class AreaHome {
private static final Log log = LogFactory.getLog(AreaHome.class);
#PersistenceContext
private EntityManager entityManager;
public void persist(Area transientInstance) {
log.debug("persisting Area instance");
try {
entityManager.persist(transientInstance);
log.debug("persist successful");
} catch (RuntimeException re) {
log.error("persist failed", re);
throw re;
}
}
public void remove(Area persistentInstance) {
log.debug("removing Area instance");
try {
entityManager.remove(persistentInstance);
log.debug("remove successful");
} catch (RuntimeException re) {
log.error("remove failed", re);
throw re;
}
}
public Area merge(Area detachedInstance) {
log.debug("merging Area instance");
try {
Area result = entityManager.merge(detachedInstance);
log.debug("merge successful");
return result;
} catch (RuntimeException re) {
log.error("merge failed", re);
throw re;
}
}
public Area findById(Integer id) {
log.debug("getting Area instance with id: " + id);
try {
Area instance = entityManager.find(Area.class, id);
log.debug("get successful");
return instance;
} catch (RuntimeException re) {
log.error("get failed", re);
throw re;
}
}
}
But when I try to call AreaHome.persist() it launchs an exception 'NullPointerException'.
I configure my project with hibernate.cfg.xml and everything works fine though:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password"><password></property>
<property name="hibernate.connection.url">jdbc:mysql://<hostname>:3306/<schema></property>
<property name="hibernate.connection.username">root</property>
<!-- <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- SQL -->
<property name="hibernate.format_sql">true</property>
<property name="hibernate.show_sql">true</property>
<!-- C3P0 -->
<property name="hibernate.c3p0.acquire_increment">2</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.timeout">180</property>
<property name="hibernate.c3p0.idle_test_period">100</property>
<!-- Classes -->
<mapping class="com.suaparte.pojo.Area" />
</session-factory>
</hibernate-configuration>
This works fine when I try:
public void persist(Area area) throws ExceptionHandler {
Session session = HibernateUtil.getSessionFactory().openSession();
try {
session.beginTransaction();
session.save(area);
session.getTransaction().commit();
} catch (HibernateException he) {
session.getTransaction().rollback();
throw new ExceptionHandler(he.getCause());
} finally {
if (session != null) {
session.close();
}
}
}
But I want to use the DAO's generated by Hibernate Tools because they have EntityManager (which is supposed to be injected, but isn't apparentely).
What I have to do ? Any idea ?
Sorry by the long question, but I wanna to be very clear about my problem.
In fact you need to implement a EntityManagerFactory.
Create a persistence.xml file that resides in the META-INF folder.
Take a look at example
http://docs.jboss.org/hibernate/entitymanager/3.6/reference/en/html_single/#setup-configuration-packaging
after the commands to create the EntityManagerFactory and EntityManager then:
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("JavaStackOver");
EntityManager entityManager = entityManagerFactory.createEntityManager();
Resolve dependencies, I used maven:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.5.6-Final</version>
</dependency>
Inject on your Dao JPA and Done!
The advantage of working with EntityManager is to have the option to change the Hibernate in futuro. Otherwise could use the Session.

JAXB Moxy- Question on how to annotate field that is xsd complex type

I am getting started with JaxB and am using the Moxy implementation. I have an industry standard xsd that I converted to Java Object Model using Jaxb. I have gotten as far as annotating simple fields like string,integer and date.
I have been searching and need to be pointed in the right direction to annotate the following field which is a xsd complex type which has 4 attributes and an optional string element. A subset of the generated code is as follows:
Conditions.java
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"condition"
})
#XmlRootElement(name = "conditions")
public class Conditions {
protected List<Conditions.Condition> condition;
public List<Conditions.Condition> getCondition() {
if (condition == null) {
condition = new ArrayList<Conditions.Condition>();
}
return this.condition;
}
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"problemDate",
"problemType",
"problemCode",
"problemStatus",
})
public static class Condition {
protected IvlTs problemDate;
//This is the field I need to annotate (problemType)
protected Cd problemType;
//The 2 below fields (problemCode, problemStatus) will also have to be annotated but I am just focusing on problemType for now
protected Cd problemCode;
protected Ce problemStatus
public void setProblemDate(IvlTs value) {
this.problemDate = value;
}
public void setProblemType(Cd value) {
this.problemType = value;
}
public void setProblemCode(Cd value) {
this.problemCode = value;
}
public void setProblemStatus(Ce value) {
this.problemStatus = value;
}
//omitted getters
}
Cd.java
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "cd", propOrder = {
"originalText",
})
public class Cd {
protected Object originalText;
#XmlAttribute(name = "code")
#XmlSchemaType(name = "anySimpleType")
protected String code;
#XmlAttribute(name = "displayName")
#XmlSchemaType(name = "anySimpleType")
protected String displayName;
#XmlAttribute(name = "codeSystem")
#XmlSchemaType(name = "anySimpleType")
protected String codeSystem;
#XmlAttribute(name = "codeSystemName")
#XmlSchemaType(name = "anySimpleType")
protected String codeSystemName;
#XmlAttribute(name = "nullFlavor")
protected NullFlavorType nullFlavor;
//ommitted getters and setters
The Cd.java class will be used for a number of other classes, not only in the Conditions.java class.
My question in particular is how would I annotate my fields for problemType in Conditions.java, where problemType has 4 attributes and one optional element.
I will not be able to directly annotate Cd.java as the xml input will differ depending on what class I am implementing (choice of 8 other classes that use Cd.java class). The existing annotations above were auto-generated by Jaxb The xml input for the Conditions.java problemType is as follows:
<PROBLEM_MODULE>
<code>24434</code> //Maps to protected String code in Cd.java;
<codeName>ICD-9</codeName> //Maps to protected String codeSystem in Cd.java;
<display>Asthma</display> //Maps to protected String displayName in Cd.java;
<codeSystem>2.564.34343.222</codeSystem> // Maps to protected String codeSystemName in Cd.java;
</PROBLEM_MODULE>
Please advise where I need to clarify my question. Ultimately I am requesting resources or tutorial to help me through this.
******UPDATE*******
Blaise's solution worked perfectly as I tested it on another project that is not as complex. Thus, the method is right, but there is something that I am getting wrong with the metadata file. I updated the Conditions.java file above, as I left out details that may effect the way I need to implement the metadata file.
My oxm.xml file
<?xml version="1.0" encoding="UTF-8"?>
<xml-bindings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
package-name="conditions.exec"
xml-mapping-metadata-complete="true">
<java-types>
<java-type name="Conditions" xml-accessor-type="FIELD">
<xml-root-element name="PROBLEM_MODULE"/>
</java-type>
<java-type name="Cd" xml-accessor-type="FIELD">
<java-attributes>
<xml-type prop-order="code codeSystem displayName codeSystemName"/>
<xml-element java-attribute="codeSystem" name="codeName"/>
<xml-element java-attribute="displayName" name="display"/>
<xml-element java-attribute="codeSystemName" name="codeSystem"/>
</java-attributes>
</java-type>
</java-types>
</xml-bindings>
*Main Class*
public static void main(String[] args) {
try {
Map<String, Object> properties = new HashMap<String, Object>(1);
properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, new File("src/conditions/exec/oxm.xml"));
JAXBContext jc = JAXBContext.newInstance(new Class[] {Conditions.class,Cd.class}, properties);
// create an Unmarshaller
Unmarshaller u = jc.createUnmarshaller();
conditions.exec.Conditions InventoryInput = (conditions.exec.Conditions) u.unmarshal(
new File("src/conditions/exec/problems.xml")); //input file
// create a Marshaller and marshal to a file
Marshaller resultMarshaller = jc.createMarshaller();
resultMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
resultMarshaller.marshal(InventoryInput, System.out);
} catch (JAXBException je) {
je.printStackTrace();
}
You can leverage EclipseLink JAXB (MOXy)'s external binding file to apply a second mapping to your class:
oxm.xml
One thing that I have set in this file is xml-mapping-metadata-complete="true", this setting tells MOXy to ignore the annotations completely and just use this file. By default the OXM file is used to supplement the annotations.
<?xml version="1.0"?>
<xml-bindings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
package-name="forum7043389"
xml-mapping-metadata-complete="true">
<java-types>
<java-type name="Root2">
<xml-root-element/>
</java-type>
<java-type name="Cd">
<xml-type prop-order="code codeSystem displayName codeSystemName"/>
<java-attributes>
<xml-element java-attribute="codeSystem" name="codeName"/>
<xml-element java-attribute="displayName" name="display"/>
<xml-element java-attribute="codeSystemName" name="codeSystem"/>
</java-attributes>
</java-type>
</java-types>
</xml-bindings>
Demo
The oxm.xml file is passed in as a property to create the JAXBContext. In the example below jc1 is created on the classes and jc2 is created on the classes and oxm.xml
package forum7043389;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
public class Demo {
public static void main(String[] args) throws Exception {
Cd cd = new Cd();
cd.setCode("24434");
cd.setCodeSystem("ICD-9");
cd.setDisplayName("Asthma");
cd.setCodeSystemName("2.564.34343.222");
JAXBContext jc1 = JAXBContext.newInstance(Root1.class);
Marshaller marshaller1 = jc1.createMarshaller();
marshaller1.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
Root1 root1 = new Root1();
root1.setCd(cd);
marshaller1.marshal(root1, System.out);
Map<String, Object> properties = new HashMap<String, Object>(1);
properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, "forum7043389/oxm.xml");
JAXBContext jc2 = JAXBContext.newInstance(new Class[] {Root2.class}, properties);
Marshaller marshaller2 = jc2.createMarshaller();
marshaller2.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
Root2 root2 = new Root2();
root2.setCd(cd);
marshaller2.marshal(root2, System.out);
}
}
Output
The following is the output from running the demo:
<?xml version="1.0" encoding="UTF-8"?>
<root1>
<cd code="24434" displayName="Asthma" codeSystem="ICD-9" codeSystemName="2.564.34343.222"/>
</root1>
<?xml version="1.0" encoding="UTF-8"?>
<root2>
<cd>
<code>24434</code>
<codeName>ICD-9</codeName>
<display>Asthma</display>
<codeSystem>2.564.34343.222</codeSystem>
</cd>
</root2>
Cd
package forum7043389;
import javax.xml.bind.annotation.*;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "cd", propOrder = {"originalText",})
public class Cd {
protected Object originalText;
#XmlAttribute(name = "code")
#XmlSchemaType(name = "anySimpleType")
protected String code;
#XmlAttribute(name = "displayName")
#XmlSchemaType(name = "anySimpleType")
protected String displayName;
#XmlAttribute(name = "codeSystem")
#XmlSchemaType(name = "anySimpleType")
protected String codeSystem;
#XmlAttribute(name = "codeSystemName")
#XmlSchemaType(name = "anySimpleType")
protected String codeSystemName;
#XmlAttribute(name = "nullFlavor")
protected NullFlavorType nullFlavor;
public Object getOriginalText() {
return originalText;
}
public void setOriginalText(Object originalText) {
this.originalText = originalText;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getCodeSystem() {
return codeSystem;
}
public void setCodeSystem(String codeSystem) {
this.codeSystem = codeSystem;
}
public String getCodeSystemName() {
return codeSystemName;
}
public void setCodeSystemName(String codeSystemName) {
this.codeSystemName = codeSystemName;
}
public NullFlavorType getNullFlavor() {
return nullFlavor;
}
public void setNullFlavor(NullFlavorType nullFlavor) {
this.nullFlavor = nullFlavor;
}
}
Root1
package forum7043389;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class Root1 {
private Cd cd;
public Cd getCd() {
return cd;
}
public void setCd(Cd cd) {
this.cd = cd;
}
}
Root2
package forum7043389;
public class Root2 {
private Cd cd;
public Cd getCd() {
return cd;
}
public void setCd(Cd cd) {
this.cd = cd;
}
}
For More Information
http://wiki.eclipse.org/EclipseLink/UserGuide/MOXy/Runtime/XML_Bindings
http://blog.bdoughan.com/2010/12/extending-jaxb-representing-annotations.html
http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html