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;
}
}
Related
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.
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.
In my application I'm using the library jersey and Apache CXF for the implementation of the REST calls . In particular, I have created my DTO, a service and a dao to insert a record into a database through the put method.
The code below is working, but my problem is when certain to pass a list of DTO that the client reports an error:
/* Client Rest */
WebResource service = clientJersey.get().resource(this.baseURI);
GaraDTO garaDTO = new GaraDTO();
garaDTO.setVersion("0");
..........................
ClientResponse response = service.path("rest").path("gare").accept(this.mediaType).put(ClientResponse.class, garaDTO);
/* DTO */
#XmlRootElement(name = "gara")
public class GaraDTO {
private Integer version;
. . . . . . . . . . . .
public GaraDTO(){
}
#XmlElement
public Integer getVersion() {
return version;
}
public void setVersion(Integer version) {
this.version = version;
}
. . . . . . . . . . . .
}
/* Service */
#Override
#PUT
#Consumes(MediaType.APPLICATION_XML)
public void putInsert(GaraDTO garaDto){
....................
//insert DB
....................
}
If, after having created an ArrayList of DTO, step this list to the client I get an error.
List<GaraDTO> listGaraDTO = new ArrayList();
listGaraDTO.add(garaDTO1);
listGaraDTO.add(garaDTO2);
..............................
ClientResponse response = service.path("rest").path("gare").accept(this.mediaType).put(ClientResponse.class, listGaraDTO);
How can I pass a list of DTO?
thanks
If you want your API to accept a List, you need to make it actually accept a List, and not a single GaraDTO.
// Client
package com.project.rest.model;
import java.util.HashSet;
import java.util.Set;
public class Client {
private Long id;
private String email;
private String lang;
public Client() {
}
public Client(Long id) {
this.id = id;
}
public Client(Long id, String email, String lang) {
this.id = id;
this.email = email;
this.lang = lang;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getLang() {
return lang;
}
public void setLang(String lang) {
this.lang = lang;
}
#Override
public String toString() {
return "Client [id=" + id + ", email=" + email + ", lang=" + lang + "]";
}
}
//ClientService
package com.project.rest;
import java.util.List;
import javax.ws.rs.Consumes;
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.core.MediaType;
import javax.ws.rs.core.Response;
import com.project.rest.model.Client;
#Path("/client")
public class ClientService {
#POST
#Path("/sendList")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response consumeJSONList(List<Client> clientList) {
String output = "consumeJSONList Client : " + clientList.toString() + "\n\n";
return Response.status(200).entity(output).build();
}
}
//JerseyClient
package com.project.rest;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.core.MediaType;
import com.project.rest.model.Client;
import com.project.rest.model.Device;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.api.json.JSONConfiguration;
public class JerseyClient {
public static void main(String[] args) {
try {
List<Client> clientList = new ArrayList<Client>();
clientList.add(new Client(1L, "pruebas#pruebas.com", "es"));
clientList.add(new Client(2L, "pruebas#pruebas.com", "es"));
clientList.add(new Client(3L, "pruebas#pruebas.com", "es"));
ClientConfig clientConfig = new DefaultClientConfig();
clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
com.sun.jersey.api.client.Client c = com.sun.jersey.api.client.Client.create(clientConfig);
WebResource webResource = c.resource("http://localhost:8080/project_rest/rest/client/sendList");
ClientResponse response = webResource.accept("application/json").type("application/json").post(ClientResponse.class, clientList);
if (response.getStatus() != 200) {
throw new RuntimeException("Failed sendClientList: HTTP error code : " + response.getStatus());
}
String output = response.getEntity(String.class);
System.out.println("sendClientList... Server response .... \n");
System.out.println(output);
} catch (Exception e) {
e.printStackTrace();
}
}
}
//POM.xml
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-bundle</artifactId>
<version>1.10-b01</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.17.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.17.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.17.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.18.1</version>
</dependency>
<dependency>
<groupId>com.owlike</groupId>
<artifactId>genson</artifactId>
<version>0.99</version>
</dependency>
I'm newbie in EJB and jUnit, and I'm trying to do Embedded testing for the simple EJB-project that running by jBoss AS 7.1.1.Final.
I've written this test:
package com.staff.test.logic;
import java.io.File;
import javax.ejb.embeddable.EJBContainer;
import javax.naming.Context;
import javax.naming.NamingException;
import org.jboss.as.embedded.EmbeddedServerFactory;
import org.jboss.as.embedded.StandaloneServer;
import org.junit.Before;
import org.junit.Test;
import com.staff.main.logic.ProjectBean;
public class ProjectBeanTest {
private StandaloneServer server;
private static EJBContainer ec;
private static Context ctx;
#Before
public void initContainer() throws Exception {
String jbossHomeDir = System.getenv("JBOSS_HOME");
System.setProperty("jboss.home","C:/eclipse/jboss-as-7.1.1.Final");
assert jbossHomeDir != null;
server = EmbeddedServerFactory.create(new File(jbossHomeDir), System.getProperties(), System.getenv(), "org.jboss.logmanager");
server.start();
ctx=server.getContext();
}
// #After
// public static void closeContainer() throws Exception {
// if (ec != null) {
// ec.close();
// }
// }
#Test
public void test() throws NamingException {
ProjectBean bean = (ProjectBean) ctx.lookup("java:global/ProjectBean");
}
}
But string
ProjectBean bean = (ProjectBean) ctx.lookup("java:global/ProjectBean") make exception:
do this exception:
javax.naming.NameNotFoundException: ProjectBean -- service jboss.naming.context.java.global.ProjectBean
at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBa sedNamingStore.java:97)
at org.jboss.as.naming.NamingContext.lookup(NamingContext.java: 178)
at org.jboss.as.naming.InitialContext.lookup(InitialContext.jav a:123)
at org.jboss.as.naming.NamingContext.lookup(NamingContext.java: 214)
at javax.naming.InitialContext.lookup(Unknown Source)
at com.staff.test.logic.ProjectBeanTest.test(ProjectBeanTest.ja va:80)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall( FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(Refl ectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(Fr ameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate( InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(Ru nBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271 )
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit 4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit 4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java: 63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java :236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java: 53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java: 229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.r un(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(Test Execution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTe sts(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTe sts(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(R emoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main( RemoteTestRunner.java:197)
I dont understand why this string do exception, because I'm newbie.
My project have a bean "ProjectBean" with interface "ProjectBeanLocal" and an entity "Post". And I have a file persistence.xml to work with Oracle 10g.
ProjectBean:
package com.staff.main.logic;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.hibernate.ejb.Ejb3Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import com.staff.main.domain.Post;
/**
* Session Bean implementation class ProjectBean
*/
#Stateless
#LocalBean
public class ProjectBean implements ProjectBeanLocal {
#PersistenceContext(unitName="StaffPU")
EntityManager manager;
public ProjectBean()
{
Ejb3Configuration cfg = new Ejb3Configuration();
cfg.configure("StaffPU", null);
SchemaExport schemaExport = new SchemaExport(cfg.getHibernateConfiguration());
//schemaExport.setOutputFile("schema.sql");
schemaExport.create(true, true);
}
#Override
public void savePost(Post post){
manager.persist(post);
}
#Override
public Post findPost(long id) {
Post post=manager.find(Post.class, id);
return post;
}
}
Interface ProjectBeanLocal:
package com.staff.main.logic;
import javax.ejb.Local;
import com.staff.main.domain.Post;
#Local
public interface ProjectBeanLocal {
void savePost(Post post);
Post findPost(long id);
}
Entity "Post":
package com.staff.main.domain;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
#Entity
public class Post implements Serializable{
private static final long serialVersionUID = 6767319776206583629L;
#Id
#SequenceGenerator(name="ent2seq",sequenceName="seq_post")
#GeneratedValue(strategy=GenerationType.SEQUENCE,generator="ent2seq")
private long id;
#Column(nullable=false)
private String name;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
And 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="StaffPU">
<jta-data-source>java:jboss/datasources/OracleDS</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
<property name="hibernate.hbm2ddl.auto" value="create" />
<!-- <property name="javax.persistence.jdbc.show_sql" value="true" /> -->
<!-- <property name="hibernate.show_sql" value="true" /> -->
</properties>
</persistence-unit>
</persistence>
You need to expose your bean with a Remote interface.
After that, you probably will need to change the JNDI entry name used to lookup the ejb reference.
You don't provide information about how the bean is deployed which, among other things, determines the binding name, but you can search the correct lookup string in the server log.
import java.io.File;
import javax.naming.InitialContext;
import org.jboss.ejb3.embedded.EJB3StandaloneBootstrap;
import org.jboss.ejb3.embedded.EJB3StandaloneDeployer;
in your pom you have to add :
<dependency>
<groupId>org.jboss.embedded</groupId>
<artifactId>jboss-embedded-all</artifactId>
<version>beta3.SP9</version>
</dependency>
<dependency>
<groupId>org.jboss.embedded</groupId>
<artifactId>thirdparty-all</artifactId>
<version>beta3.SP9</version>
</dependency>
you have to add :
embedded-jboss-beans.xml
bean.xml,default.persistence.properties
ejb3-interceptors-aop.xml
into your resources folder and jndi.properties too whtch contains :
java.naming.factory.initial=org.jnp.interfaces.LocalOnlyContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
and you test class must contains :
EJB3StandaloneBootstrap.boot(null);
EJB3StandaloneBootstrap.scanClasspath();
EJB3StandaloneBootstrap.deployXmlResource(embeded.xml)
deployer = EJB3StandaloneBootstrap.createDeployer();
deployer.getArchives().add(new File("target/classes").toURI().toURL());
deployer.create();
deployer.start();
InitialContext context = new InitialContext();
and you look up your ejb
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"