This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.
Currently, in Java EE 5 project type, a complicated set of classes is generated for each entity class. E.g. for Customer class there are : CustomersResource CustomerResource CustomersConverter CustomerConverter UriResolver // one for all resources PersistenceService // one for all resources We can re-use the JPA controller wizard and generate a RESTFacade class that will delegate to JpaController: CustomerRESTFacade // will delegate to CustomerJpaController CustomerJpaController IllegalOrphanException // one for all resources NonexistingEntityException // one for all resources PreexistingEntityException // one for all resources RollbackFailureException // one for all resources Thus, basically, we can reduce the number of generated classes, and also be compatible with other Netbeans feature (JPA controller) This is the sample code that can be generated : @Path("/customer") public class CustomerRESTFacade { private CustomerJpaController jpaController; public CustomerRESTFacade() { jpaController = getJpaController(); } /** get all Customers */ @GET @Produces({"application/xml", "application/json"}) public List<Customer> findCustomerEntities() { return jpaControler.findCustomerEntities(); } /** create new Customer */ @PUT @Consumes({"application/xml", "application/json"}) public Response create(Customer entity) { try { jpaControler.create(entity); return Response.created("..").build(); } catch (Exception ex) { return Response.notModified(ex.getMessage()).build(); } } /** get Customers count */ @GET @Path("count") @Produces("text/plain") public String getCount() { return String.valueOf(jpaControler.getCustomerCount()); } // similarly delegate to other JpaController methods, like // edit // destroy // findCustomer private CustomerJpaController getJpaController() { try { EntityManagerFactory emf = (EntityManagerFactory) new InitialContext().lookup("java:comp/env/persistence-factory"); UserTransaction utx = (UserTransaction) new InitialContext().lookup("java:comp/UserTransaction"); return new CustomerJpaController(utx, emf); } catch (NamingException ex) { throw new RuntimeException(ex); } } } Also that would be necessary to insert 2 entries to web.xml : <resource-ref> <res-ref-name>UserTransaction</res-ref-name> <res-type>javax.transaction.UserTransaction</res-type> <res-auth>Container</res-auth> </resource-ref> <persistence-unit-ref> <persistence-unit-ref-name>persistence-factory</persistence-unit-ref-name> <persistence-unit-name>WebApplicationPU</persistence-unit-name> </persistence-unit-ref> Please, review the suggested code. I've already tested that.
> @Path("/customer") > public class CustomerRESTFacade { According to "Table EE.5-1 Component classes supporting injection" in EE6 spec (page 67) 'JAX-RS root resource classes' support injection so you should not need JNDI lookup in CustomerRESTFacade but injection should do the trick.
> According to "Table EE.5-1 Component classes supporting injection" in EE6 spec Yes, but this is EE 5. Does it also apply? I think in the EE 6 case injection is used already - see also bug 181161, from which this one was spun off (possibly bug 173984 is also related).
Yes, this is about Java EE 5, where the injections are not fully supported in REST resources. For Java EE 6 (REST from Entity), I've reported another enhancement: - issue 189761
(In reply to comment #3) > Yes, this is about Java EE 5, where the injections are not fully supported in > REST resources. > > For Java EE 6 (REST from Entity), I've reported another enhancement: > - issue 189761 Right, in EE5 injection is required only for JAX-WS but not for JAX-RS.
Milan, I tried to find somewhere specified what exactly must be done for EE5 and I was not successful but: * several sources say that UserTransction is always available under JNDI name java:comp/UserTransaction and therefore web.xml entry should not be needed. I tested it on GFv2 and it does work without web.xml record * to access EntityManagerFactory for your PU you need to map JNDI entry to your PU but instead of web.xml record you could just add @PersistenceContext(unitName="WebApplicationPU", name="persistence-factory") to class level of you POJO. Again, I tested it on GFv2 and it works. I would prefer to avoid web.xml if possible as it is extra configuration source. Can you double check please? Thx.
Thanks, Tested with GlassFish V31 < * several sources say that UserTransction is always available under JNDI name java:comp/UserTransaction and therefore web.xml entry should not be needed. I tested it on GFv2 and it does work without web.xml record - works fine < * to access EntityManagerFactory for your PU you need to map JNDI entry to your PU but instead of web.xml record you could just add @PersistenceContext(unitName="WebApplicationPU", name="persistence-factory") to class level of you POJO. Again, I tested it on GFv2 and it works. - I got: java.lang.ClassCastException: com.sun.enterprise.container.common.impl.EntityManagerWrapper cannot be cast to javax.persistence.EntityManagerFactory Can you David evaluate if this is a GlassFish bug or not. I wonder if there is any specification how to create an instance of EntityManagerFactory properly.
In GlassFish V3, the injection for EntityManagerFactory object simply fails: object isn't initialized(null) David - have you tested that on some REST resource inside the web container?
< * several sources say that UserTransction is always available under JNDI name java:comp/UserTransaction and therefore web.xml entry should not be needed. I tested it on GFv2 and it does work without web.xml record It's likely because the UserTransaction JNDI resource is, likely by default, available in GlassFish, unlike in Tomcat server: see: http://tomcat.apache.org/tomcat-5.5-doc/jndi-resources-howto.html
Sorry for confusing you Milan. If you need to lookup EntityManagerFactory then you must use @PersistenceUnit annotation on your class. When you use @PersistenceContext annotation then EntityManager will be looked up. (In reply to comment #8) > It's likely because the UserTransaction JNDI resource is, likely by default, > available in GlassFish, unlike in Tomcat server: The problem with Tomcat is that it is not EE server - it is just web container and so likely persistence annotations may or may not work as Tomcat does not come with persistence support. I would be tempted to implement this properly for EE servers and later either handle Tomcat specially (by generating web.xml records) or ... do nothing? Let user's fix this for Tomat? Wait for EE Web Profile Tomcat? I'm not sure. What do you think?
(In reply to comment #5) > * to access EntityManagerFactory for your PU you need to map JNDI entry to your > PU but instead of web.xml record you could just add > @PersistenceContext(unitName="WebApplicationPU", name="persistence-factory") to > class level of you POJO. Put this on hold for now: JPA spec talks about @PersistenceContext only in context of EJBs or managed objects. Applying it on POJOs might not be complaint with the spec despite it being supported by GlassFish implementation and so we should not recommend it. I'm trying to clarify this.
I'm trying to follow suggested code pattern and have realized the problem with JPA Controller. For some reason it doesn't work. I need a help with generated controller. So the problem has no any relation to THIS RFE. Here are the steps which I have used : - Create a WEB JEE5 project with target server GF2. - Create entities for table(s) ( I have used sample Derby database and tables: customer and discount code ). - Create JPA controller classes from entities . - This step is just interface to call JPA controller methods: create RESTful web service and method of WS which delegates "create()" method call of JPA controller. Additional info : - See the code from original description of this issue for access to JPA controller - I'm using TopLink Essentials persistence provider. Call of WS method ( f.e. using the test RESTful WS action of NB ) lead to exception in the JPA Controller. See attached exception. Please note that it happens on call of start transaction method of entity manager: em.getTransaction().begin(); We need to resolve this issue before I will decide to change generated code.
Created attachment 103629 [details] stacktrace
looks like an issue for me, code for jpa controller is different from one generated in case of jsf from entities.
OK, thanks, I will file a bug.
I have filed a bug #192981 about inconvenient behavior of generated JPA Controller . We can use different classes generation approach: do not rely on existed functionality of JPA controller. The required code from JPA controller could be put into generated RESTFacade classes directly. But it seems it is not a good solution. Generated code could be potentially duplicate by developer in case of some non trivial entities usage in Web application. Also the current generation strategy has some preference against final result of "improvement" version. Although the code becomes plainer but result of methods which return collection is less obvious. XxxxsConverter is used as aggregate class for collection of entities. It allows to generate XML response when collection entities should be returned. Otherwise ( List<Xxxx> is return type of method ) json MIME type is used and response is not XML content. User should adopt generated code for getting XML content instead of json. The simplest way to adopt the code is creation of XXXxxsConverter. As result I postpone the decision for this issue to future. It seems it is not so obvious that suggested approach is better than existed one. And it is also blocked by #192981
current behavior generate proper jpa controller in case of jsf from entities, 192981 is issue for stand alone jpa controller generation, is it really blocker for this enhancement?
Hm, I need to investigate the possibility of JPA controller generation code reusage ( from JSF Pages from Entities ). It seems that generated code ( JPA controllers ) is good enough for the current issue. Probably the JPA controller code generation strategy could be really used and #192981 doesn't block this bug.
OK , I have investigated the "JSF Pages from Entity Classes..." wizard code. The short conclusion : it cannot be used for resolving current RFE and I need to have bug #192981 fixed. So issue #192981 is still stopper. Detailed explanation : Generation code for "JSF Pages..." actions is located inside web.jsf module which is not good as dependency for websvc.rest definitely even without detailed code investigation. "JSF Pages..." wizard is written in the way which doesn't allow direct reusage. It's purpose is not "JPA controller" generation but all source code required for JSF generation. So it is strictly JSF centered. It is not so easy to distinguish and reuse just "JPA controller" generation logic from the whole generation logic. On the other hand "JPA Controller Classes from Entity Classes" wizard has a very good design which can be reused with minimal changes. From my point of view : "JSF Pages..." generation logic SHOULD reuse itself "JPA Controller Classes from Entity Classes" generation logic to avoid code duplication. So I really need to have #192981 fixed.
(In reply to comment #18) > From my point of view : "JSF Pages..." generation logic SHOULD reuse itself > "JPA Controller Classes from Entity Classes" generation logic to avoid > code duplication. Denis, could you file an issue please for it to happen? Thanks.
Sorry I was wrong. There is no code duplication. I have missed the call of JpaControllerIterator.generateJpaControllers() method inside "JSF Pages..." wizard iterator. The latter code has a similar method names for JSF controllers which I mixed up. So the code is perfectly reused.
The fix for this RFE requires a huge number of code modification. It will have a strong impact on important RESTful from entities/DB functionality. Common generation code strategy needs to be rewritten along with various cases: 1) additional generation logic for JEE5 2) additional generation logic for Spring The current approach will dramatically change. So it is very risky to do this for upcoming 7.0 release. I'm working on this RFE but result will be committed to the trunk only for next version .
If the changes are large, then I agree it should be deferred to the next release.
The code changes dramatically . It concerns the functionality under subject and related functionality. I think the rewriting of the existing code will be ready on the next week. But as I understand WS functionality is not tested seriously. As result of this RFE fix one needs to perform deep testing for 1) RESTful from Enities 2) RESTful from DB Each item for : JEE6, JEE5 , String support. There are a lot of testing. So I really afraid that the fix could break existing functionality.
web-main changeset: 193977:d15e95287f01
Not in 7.0.1 -> TM=Dev.
Integrated into 'main-golden' Changeset: http://hg.netbeans.org/main-golden/rev/2eb7d9687b23 User: Vladimir Riha <vriha@netbeans.org> Log: QA - updated REST tests to be consistent with #189723 and some other minor updates