REST Works on some computers - rest

This is really confusing, i have a rest service that works on some computers but refuses to work on others, no idea why.
The project is using Maven, EJB and glassfish
This is the rest service:
#Path("/")
public class ArticleService {
#EJB
private LocalArticle articleEJB;
#GET
#Produces(MediaType.APPLICATION_XML)
#Path("article/{articleId}")
public Article getArticleXML(#PathParam("articleId") int id) {
return articleEJB.getArticleById(id);
}
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("article/{articleId}")
public Article getArticleJSON(#PathParam("articleId") int id) {
return articleEJB.getArticleById(id);
}
}
The return value is a object, and if i instead return article.getName i get a 200 response, however if i try to return the entire object i get 500
Here is a rest management class(I'm not sure what this does, I followed an example from a book):
#ApplicationPath("rest")
public class ArticleMgmtRESTApplication extends ResourceConfig {
public ArticleMgmtRESTApplication () {
packages("se.alager.rest.ws.services");
}
}
}
Here is the Article in question:
#Entity
#NamedQueries({
#NamedQuery(name="Article.findAll", query="SELECT a FROM Article a"),
#NamedQuery(name="Article.findById", query="SELECT a FROM Article a WHERE a.id = :id")
})
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Article implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name="id_article")
#XmlAttribute
private int id;
private int amount;
private String description;
private String name;
}
This exact code works flawlessly for mt friend, but I can't seem to get it to work, any ideas as to why?
Here is the Glassfish log for the error (ther was some 500 more lines of log, I hope this is relevant, I have no idea what I'm doing here)
[2016-10-20T16:31:44.140+0200] [glassfish 4.1]
[INFO] [] [org.jboss.weld.Bootstrap]
[tid: _ThreadID=142 _ThreadName=admin-listener(7)] [timeMillis: 1476973904140]
[levelValue: 800] [[
WELD-000119: Not generating any bean definitions from
org.glassfish.jersey.server.internal.inject.ParamConverters$CharacterProvider
because of underlying class loading error: Type [unknown] not found.
If this is unexpected, enable DEBUG logging to see the full error.]]
[2016-10-20T16:31:45.000+0200] [glassfish 4.1] [INFO] []
[org.glassfish.jersey.servlet.init.JerseyServletContainerInitializer]
[tid: _ThreadID=142 _ThreadName=admin-listener(7)] [timeMillis: 1476973905000]
[levelValue: 800] [[
Registering the Jersey servlet application, named
se.alager.rest.ws.ManagementRESTApplication,
at the servlet mapping /rest/*, with the Application class of the same name.]]

Related

EclipseLink JPA converter subclasses doesn't work

I use payara5 (with EclipseLink). It looks like I can't use subclasses with a JPA converter. With wildfly (and Hibernate), it works fine.
The problem comes from this query :
#Override
public List<Employee> findByStatus(Employee.Status status) {
return em.createNamedQuery("Employee.findByStatus", Employee.class)
.setParameter("status", status)
.getResultList();
}
It looks like, if the converter is a subclass, EclipseLink is not able to convert the parameter "status" into a string.
Without the subclass, it works just fine. Is it a bug in EclipseLink ?
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>
<class>fjp.converter.entity.converter.StatusConverterSubClass</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
<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>
Entity :
package fjp.converter.entity;
import java.io.Serializable;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.persistence.Convert;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
#NamedQuery(name="Employee.findByStatus", query="select e from Employee e where e.status=:status")
#Entity
public class Employee implements Serializable{
private static final long serialVersionUID = 1L;
public enum Status implements HasCode {
SENIOR("SENIOR"),
JUNIOR("JUNIOR");
private String code;
private Status(String s) {
this.code = s;
}
#Override
public String getCode() {
return this.code;
}
private static Map<String, Status> map = Stream.of(values()).collect(Collectors.toMap(Status::getCode, Function.identity()));
public static Status fromString(String code) {
return map.get(code);
}
}
#Id
private long id;
// #Convert(converter = fjp.converter.entity.converter.StatusConverter.class)
#Convert(converter = fjp.converter.entity.converter.StatusConverterSubClass.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());
}
#Override
public boolean equals(Object o) {
if(o == this) return true;
if(!(o instanceof Employee)) return false;
Employee e = (Employee) o;
return e.getId() == getId();
}
#Override
public int hashCode() {
return Long.hashCode(getId());
}
}
Interface HasCode :
package fjp.converter.entity;
public interface HasCode {
String getCode();
}
StatusConverter :
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;
}
}
}
StatusConverterSubClass :
package fjp.converter.entity.converter;
import javax.persistence.Converter;
import fjp.converter.entity.Employee.Status;
#Converter
public class StatusConverterSubClass extends EnumCodeConverter<Status> {
public StatusConverterSubClass() {
super(Status::fromString);
}
}
Converter base class :
package fjp.converter.entity.converter;
import java.util.function.Function;
import javax.persistence.AttributeConverter;
import fjp.converter.entity.HasCode;
public class EnumCodeConverter<T extends HasCode> implements AttributeConverter<T, String> {
private final Function<String, ? extends T> fromString;
protected EnumCodeConverter(Function<String, ? extends T> fromString) {
this.fromString = fromString;
}
#Override
public String convertToDatabaseColumn(T attribute) {
return attribute == null ? null : attribute.getCode();
}
#Override
public T convertToEntityAttribute(String code) {
if(code == null) return null;
T r = this.fromString.apply(code);
if(r == null) {
throw new IllegalArgumentException(String.format("unknow code: '%s', '%s'", code, this.getClass()));
}
return r;
}
}
dao :
package fjp.converter.dao;
import java.util.List;
import fjp.converter.entity.Employee;
public interface EmployeeDAO {
public List<Employee> findByStatus(Employee.Status status);
}
daoimpl :
package fjp.converter.dao;
import java.util.List;
import javax.ejb.Stateless;
import javax.ejb.Local;
import javax.persistence.PersistenceContext;
import javax.persistence.EntityManager;
import fjp.converter.entity.Employee;
#Local(EmployeeDAO.class)
#Stateless
public class EmployeeDAOImpl implements EmployeeDAO {
#PersistenceContext
private EntityManager em;
#Override
public List<Employee> findByStatus(Employee.Status status) {
return em.createNamedQuery("Employee.findByStatus", Employee.class)
.setParameter("status", status)
.getResultList();
}
}
Test servlet :
package fjp.converter.servlet;
import javax.inject.Inject;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import fjp.converter.dao.EmployeeDAO;
import fjp.converter.entity.Employee.Status;
#WebServlet("/test")
public class Test extends HttpServlet {
private static final long serialVersionUID = 1L;
#Inject
private EmployeeDAO dao;
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
Status status = Status.SENIOR;
var list = dao.findByStatus(status);
System.out.println("FJP: " + list.size());
}
}
And payara logs :
[2021-11-11T11:42:56.565+0100] [Payara 5.2021.3] [CONFIG] [] [org.eclipse.persistence.default] [tid: _ThreadID=185 _ThreadName=admin-thread-pool::admin-listener(11)] [timeMillis: 1636627376565] [levelValue: 700] [[
The default table generator could not locate or convert a java type (class fjp.converter.entity.Employee$Status) into a database type for database field (EMPLOYEE.STATUS). The generator uses "java.lang.String" as default java type for the field.]]
[2021-11-11T11:43:21.771+0100] [Payara 5.2021.3] [AVERTISSEMENT] [AS-EJB-00056] [javax.enterprise.ejb.container] [tid: _ThreadID=76 _ThreadName=http-thread-pool::http-listener-1(5)] [timeMillis: 1636627401771] [levelValue: 900] [[
A system exception occurred during an invocation on EJB EmployeeDAOImpl, method: public java.util.List fjp.converter.dao.EmployeeDAOImpl.findByStatus(fjp.converter.entity.Employee$Status)]]
[2021-11-11T11:43:21.772+0100] [Payara 5.2021.3] [AVERTISSEMENT] [] [javax.enterprise.ejb.container] [tid: _ThreadID=76 _ThreadName=http-thread-pool::http-listener-1(5)] [timeMillis: 1636627401772] [levelValue: 900] [[
javax.ejb.EJBException: Exception [EclipseLink-3002] (Eclipse Persistence Services - 2.7.7.payara-p3): org.eclipse.persistence.exceptions.ConversionException
Exception Description: The object [SENIOR], of class [class java.lang.String], from mapping [org.eclipse.persistence.mappings.DirectToFieldMapping[status-->EMPLOYEE.STATUS]] with descriptor [RelationalDescriptor(fjp.converter.entity.Employee --> [DatabaseTable(EMPLOYEE)])], could not be converted to [class fjp.converter.entity.Employee$Status].
at com.sun.ejb.containers.EJBContainerTransactionManager.processSystemException(EJBContainerTransactionManager.java:723)
at com.sun.ejb.containers.EJBContainerTransactionManager.completeNewTx(EJBContainerTransactionManager.java:652)
at com.sun.ejb.containers.EJBContainerTransactionManager.postInvokeTx(EJBContainerTransactionManager.java:482)
at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4592)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2125)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2095)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:220)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:90)
at com.sun.proxy.$Proxy392.findByStatus(Unknown Source)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.jboss.weld.util.reflection.Reflections.invokeAndUnwrap(Reflections.java:410)
at org.jboss.weld.module.ejb.EnterpriseBeanProxyMethodHandler.invoke(EnterpriseBeanProxyMethodHandler.java:134)
at org.jboss.weld.bean.proxy.EnterpriseTargetBeanInstance.invoke(EnterpriseTargetBeanInstance.java:56)
at org.jboss.weld.module.ejb.InjectionPointPropagatingEnterpriseTargetBeanInstance.invoke(InjectionPointPropagatingEnterpriseTargetBeanInstance.java:68)
at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:106)
at fjp.converter.dao.EmployeeDAO$1921730137$Proxy$_$$_Weld$EnterpriseProxy$.findByStatus(Unknown Source)
at fjp.converter.servlet.Test.doGet(Test.java:36)
logs with FINEST level
[2021-11-13T09:19:12.784+0100] [Payara 5.2021.3] [LE PLUS PRÉCIS] [] [org.eclipse.persistence.default] [tid: _ThreadID=173 _ThreadName=admin-thread-pool::admin-listener(6)] [timeMillis: 1636791552784] [levelValue: 300] [[
Missing class details for [fjp/converter/entity/converter/StatusConverterSubClass].]]
[2021-11-13T09:19:12.784+0100] [Payara 5.2021.3] [LE PLUS PRÉCIS] [] [org.eclipse.persistence.default] [tid: _ThreadID=173 _ThreadName=admin-thread-pool::admin-listener(6)] [timeMillis: 1636791552784] [levelValue: 300] [[
Using existing class bytes for [fjp/converter/entity/converter/StatusConverterSubClass].]]
[2021-11-13T09:19:12.785+0100] [Payara 5.2021.3] [LE PLUS PRÉCIS] [] [org.eclipse.persistence.default] [tid: _ThreadID=173 _ThreadName=admin-thread-pool::admin-listener(6)] [timeMillis: 1636791552785] [levelValue: 300] [[
Missing class details for [fjp/converter/entity/converter/EnumCodeConverter].]]
[2021-11-13T09:19:12.785+0100] [Payara 5.2021.3] [LE PLUS PRÉCIS] [] [org.eclipse.persistence.default] [tid: _ThreadID=173 _ThreadName=admin-thread-pool::admin-listener(6)] [timeMillis: 1636791552785] [levelValue: 300] [[
Using existing class bytes for [fjp/converter/entity/converter/EnumCodeConverter].]]
[2021-11-13T09:19:12.790+0100] [Payara 5.2021.3] [INFOS] [] [org.eclipse.persistence.session./file:/home/frederic/payara5/glassfish/domains/domain1/applications/converter-1.0/WEB-INF/classes/_primary] [tid: _ThreadID=173 _ThreadName=admin-thread-pool::admin-listener(6)] [timeMillis: 1636791552790] [levelValue: 800] [[
EclipseLink, version: Eclipse Persistence Services - 2.7.7.payara-p3]]
[2021-11-13T09:19:12.809+0100] [Payara 5.2021.3] [CONFIG] [] [org.eclipse.persistence.default] [tid: _ThreadID=173 _ThreadName=admin-thread-pool::admin-listener(6)] [timeMillis: 1636791552809] [levelValue: 700] [[
The default table generator could not locate or convert a java type (class fjp.converter.entity.Employee$Status) into a database type for database field (EMPLOYEE.STATUS). The generator uses "java.lang.String" as default java type for the field.]]
It's definitely a bug in EclipseLink.
Fortunately, there is a workaround. The AttributeConverter interface must be added to the subclass. It's totally useless as the superclass already implements it.

Problem with DiscriminatorValue - The abstract schema is unknown

I must run project with JEE and EclipseLink 2.6.1. Maven successfully compiles the project, but when I put . jar on Payara and try to run it it gets problems of the type:
The abstract schema type 'NetServer'; is unknown.
The state field path 'netserver.active'; cannot be resolved to a valid type.
The problem occurs in queries with all entities with annotations #DiscriminatorValue. Entity looks like this:
Main class (Servers) :
#Entity
#Table("Servers")
#DiscriminatorColumn(
name = "SERVER_TYPE",
discriminatorType = DiscriminatorType.STRING
)
#DiscriminatorValue("servers")
public class Servers{
#Id
private Long id;
private String name;
private String hostname;
private Boolean active;
//getters& setters
}
Netserver:
#Entity
#DiscriminatorValue("netserver")
public class NetServer extends Server{
private String url;
public Netserver();
public Netserver(Server server){super(server);}
//getters&setters
}
And I wonder what the problem is that he throws away exceptions?

Upgrading from Spring Data 1.11 to Spring Data 2.0 results in "No property delete found for type SimpleEntity!"

I have a simple project with the classes below defined. It works just fine in spring-boot 1.5.4, spring-data-commons 1.13, and spring-data-jpa 1.11.
When I upgrade to spring-boot 2.0.0.M5, spring-data-commons 2.0.0 and spring-data-jpa-2.0.0, I get a PropertyReferenceException at startup that says "No property delete found for type SimpleEntity!" Unfortunately, I can't get the stack trace out of
the computer I get the error in, it is very locked down for security.
Any ideas? Other posts I found don't seem to match my situation.
Here are the classes (altered the names, but you get the idea):
package entity;
#MappedSuperclass
public abstract class BaseEntity implements Serializable {
....
}
package entity;
#Entity
#Table(schema = "ENTITIES", name = "SIMPLE")
public class SimpleEntity extends BaseEntity {
#Column(name = "ID")
private Long id;
#Column(name = "CODE")
private String code;
#Column(name = "NAME")
private String name;
... getters and setters ...
}
package repository;
imoport org.springframework.data.repository.Repository
public interface SimpleRepository extends Repository<SimpleEntity, Long> {
public SimpleEntity save(SimpleEntity entity);
public List<SimpleEntity> save(List<SimpleEntity> entities);
public void delete(Long id);
public SimpleEntity findOne(Long id);
public List<SimpleEntity> findAllByOrderByNameAsc();
public List<SimpleEntity> findByCode(String code);
public List<SimpleEntity> findByNameIgnoreCaseOrderByNameAsc(String name);
}
Turns out there is a breaking change in Spring Data 2.0 CrudRepository interface. The error I received occurs under the following conditions:
You have a 1.x Sping Data project
You have an interface that extends Repository directly, not a subinterface like CrudRepository
Your Repository subinterface declares the "void delete(ID)" method found in CrudRepository (in my case "void delete(Long)"
You update to Spring Data 2.x
The problem is that CrudRepository in 2.x no longer has a "void delete(ID)" method, it was removed, and a new method "void deleteById(ID)" was added.
When Spring data sees a delete method signature it doesn't recognize, it produces an error about your entity class missing a delete property - this is true of both 1.2 and 2.x.

Jersey JAX-RS Glassfish 4 throwing java.lang.IllegalStateException

I am creating a simple RESTful service
#Path("/book")
#Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
#Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
#Stateless
public class RestBookService {
#PersistenceContext(unitName="bookPU")
private EntityManager em;
#Context
protected UriInfo uriInfo;
#POST
public Response createBook(Book book) {
if (book == null)
throw new BadRequestException();
em.persist(book);
URI bookUri = uriInfo.getAbsolutePathBuilder().path(book.getId() + "").build();
return Response.created(bookUri).build();
}
}
The Book is simple JPA entity
#Entity
#XmlRootElement
public class Book {
static Logger log = Logger.getLogger(Book.class.getName());
public static final String FIND_ALL = "Book.find_all";
#Id
#GeneratedValue
private int id;
#Column(nullable=false)
private String title;
#Column
private Float price;
}
//Just giving a relevant code. There are getters/setters and the constructor
I am deploying the service using Maven on Glassfish 4.1
I am using
Jersey Container 2.13
Hibernate 4.3.5 Final
Mysql 5.1
and when I try to create a book using cURL as follows
curl -X POST --data-binary "<book><price>12.5</price><title>Book Title</title></book>" -H "Content-Type: application/xml" http://localhost:8080/book-service/rs/book -v
It is throwing following exception.
StandardWrapperValve[jersey-serlvet]: Servlet.service() for servlet jersey-serlvet threw exception
java.lang.IllegalStateException: Not inside a request scope.
at jersey.repackaged.com.google.common.base.Preconditions.checkState(Preconditions.java:149)
at org.glassfish.jersey.process.internal.RequestScope.current(RequestScope.java:228)
at org.glassfish.jersey.process.internal.RequestScope.findOrCreate(RequestScope.java:156)
at org.jvnet.hk2.internal.MethodInterceptorImpl.invoke(MethodInterceptorImpl.java:74)
at org.jvnet.hk2.internal.MethodInterceptorInvocationHandler.invoke(MethodInterceptorInvocationHandler.java:62)
at com.sun.proxy.$Proxy239.getAbsolutePathBuilder(Unknown Source)
at com.services.bookrestservice.rest.RestBookService.createBook(RestBookService.java:44)
[There is another question similar to this but I have done exactly the same which is given in the answer still I am getting the exception. Also, I have gone through https://java.net/jira/browse/JERSEY-2241 but it seems to be in resolved state with the resolution as cannot reproduce. ]
Can somebody please help me.
EDIT1
I have changed from Stateless annotation to RequestScoped annotation as suggested by #HankCa. It is throwing following exception now.
'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:281)
at com.services.bookrestservice.rest.RestBookService.createBook(RestBookService.java:44)
'
Not sure why this exception because it is already in persistentcontext.
EDIT2
#HankCa suggested I did the following change.
Removed
#Context
protected UriInfo uriInfo;
And updated the method signature as
#POST
public Response createBook(Book book, #Context UriInfo uriInfo) {
And the service is working as expected. Thanks HankCa for your help.
Yes I stared at this one for far too long and my solution was as you found at Why is my Jersey JAX-RS server throwing a IllegalStateException about not being in RequestScope?. This was a year ago and I haven't hit it again (though I have been out of EJB land for a while) so I'll give it my best shot.
Specifically I would make these mods:
Add #RequestScoped
Put the #Context UriInfo uriInfo in the method or class. In the end i seemed to have gone in the method like:
This is code (and this is a line to separate the list from the code so the code shows as code!)
#Path("/user")
#Produces({ MediaType.APPLICATION_JSON })
#Consumes({ MediaType.APPLICATION_JSON })
#RequestScoped
public class UserResource {
...
#PermitAll
#POST
public Response signupUser(CreateUserRequest request, #Context UriInfo uriInfo) {
AuthenticatedUserToken token = userService.createUser(request, Role.authenticated);
verificationTokenService.sendEmailRegistrationToken(token.getUserId());
URI location = uriInfo.getAbsolutePathBuilder().path(token.getUserId()).build();
return Response.created(location).entity(token).build();
}
I hope that helps!
Cheers,
bbos

JPA Warning: "No mapping is associated with the state field path 't.progress'"

I'm using JPA (EclipseLink 2.4.1) with a mapping-file containing named-queries. Eclipse shows me the following warning message in my mapping file:
No mapping is associated with the state field path 't.progress'.
The warning is of the type JPA Problem. The corresponding lines in my named-queries.xml-file look like this:
<named-query name="FinishedTasks">
<query><![CDATA[SELECT t FROM Task t WHERE t.progress = 100]]></query>
</named-query>
However, the query runs fine when executed, so no warning in run-time.
Here's what the file Task.java looks like (excerpt):
#Entity
public class Task extends Issue {
private Integer progress = 0;
public Integer getProgress() {
return progress;
}
public void setProgress(final Integer progress) {
this.progress = progress;
}
}
Issue.java looks like this (excerpt):
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
public class Issue implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
public long getId() {
return id;
}
public void setId(final long id) {
this.id = id;
}
}
I have no warnings about queries using Issue.
So my question is, how do I get rid of the warning? And does the warning have some implication I'm not aware of (as said, the query runs fine).
No mapping is associated with the state field path 't.progress'
I believe this is totally due to the Eclipse JPA Details View (orm.xml editor) and has nothing to do with EclipseLink nor JPA in general. The warning is reminding you that the Named Query is using a JPA query path (t.progress) that is not mapped in the mapping file. The View / xml editor is not analysing the metadata of your java classes, so is not aware whether the it is mapped via JPA annotations.
i.e. the tool is doing the best job for you it possibly can give it's technology / scope limitations.
Solution:
understand what the message is saying, manually ensure that the warning is addressed via JPA annotations (OR if you really must, insert the approprate Entity Mappings into your entity mapping XML file), and move on...
:^)
This seems to be wrong.
<named-query name="FinishedTasks">
<query><![CDATA[SELECT t FROM Task t WHERE t.progress = 100]]></query>
</named-query>
I can't find anything like that with CDATA. See examples at http://wiki.eclipse.org/EclipseLink/Examples/JPA/QueryOptimization
Try this in your named-queries.xml. Or use #NamedQuery annotation like below.
<named-query name="FinishedTasks">
<query>SELECT t FROM Task t WHERE t.progress = 100</query>
</named-query>
I just build a test project and use this
package test;
import javax.persistence.Entity;
import javax.persistence.NamedQuery;
#Entity
#NamedQuery(name = "FinishedTasks",
query = "SELECT t FROM Task t WHERE t.progress = 100")
public class Task extends Issue {
private Integer progress = 0;
public Integer getProgress() {
return progress;
}
public void setProgress(final Integer progress) {
this.progress = progress;
}
}
Using JUnit didn't resolve to any warning.
package test;
import static org.junit.Assert.assertEquals;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class TaskTest {
private static EntityManager em;
#BeforeClass
public static void setUpBeforeClass() throws Exception {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("test");
em = factory.createEntityManager();
em.getTransaction().begin();
Task t = new Task();
t.setProgress(100);
em.persist(t);
em.getTransaction().commit();
}
#AfterClass
public static void tearDownAfterClass() throws Exception {
em.close();
}
#Test
public void test() {
Query q = em.createNamedQuery("FinishedTasks");
List<?> list = q.getResultList();
int expected = 1;
int actual = list.size();
assertEquals(actual, expected);
}
}
My log
[EL Info]: 2013-05-01
21:57:55.561--ServerSession(1763596)--EclipseLink, version: Eclipse
Persistence Services - 2.4.1.v20121003-ad44345 [EL Info]: connection: 2013-05-01