问题
I'm heaving some trouble while learning ejb. All I want is write a simple app operatign on database. Here's my code:
Servlet - Main.java
package main;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(name = "Main", urlPatterns = {"/"})
public class Main extends HttpServlet {
@EJB
private NoteSB noteSB;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
List<Note> notes = noteSB.getNotes();
for( int i=0,len=notes.size() ; i<len ; ++i ) {
out.println(notes.get(i));
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
@Override
public String getServletInfo() {
return "Short description";
}
}
Entity - Note.java
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package main;
import java.io.Serializable;
import java.security.Timestamp;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "NOTES")
public class Note implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String note;
private Timestamp date;
public Note(){}
public Note(String note, Timestamp date) {
this.note = note;
this.date = date;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
if (!(object instanceof Note)) {
return false;
}
Note other = (Note) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
@Override
public String toString() {
return "Note["+ this.date +"]: " + this.note;
}
}
Stateless Session bean - NoteSB.java
package main;
import java.util.List;
import javax.annotation.PreDestroy;
import javax.ejb.Stateless;
import javax.ejb.LocalBean;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@Stateless
@LocalBean
public class NoteSB {
@PersistenceContext(name = "jee-warPU")
private EntityManager em;
public void newNote(Note n) {
em.persist(n);
}
public List<Note> getNotes() {
return em.createNativeQuery("SELECT * FROM NOTES").getResultList();
}
@PreDestroy
public void destroy() {
em.close();
}
}
persistance.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="jee-warPU" transaction-type="JTA">
<jta-data-source>java:comp/DefaultDataSource</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.schema-generation.database.action" value="create"/>
</properties>
</persistence-unit>
</persistence>
And here's my stack trace:
Info: file:/C:/Users/BB/Documents/NetBeansProjects/jee/jee-war/build/web/WEB-INF/classes/_jee-warPU logout successful
Info: visiting unvisited references
Info: visiting unvisited references
Info: visiting unvisited references
Info: visiting unvisited references
Info: visiting unvisited references
Info: EclipseLink, version: Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd
Info: file:/C:/Users/BB/Documents/NetBeansProjects/jee/jee-war/build/web/WEB-INF/classes/_jee-warPU login successful
Info: Portable JNDI names for EJB NoteSB: [java:global/jee-war/NoteSB, java:global/jee-war/NoteSB!main.NoteSB]
WARN: WELD-000411: Observer method [BackedAnnotatedMethod] org.glassfish.sse.impl.ServerSentEventCdiExtension.processAnnotatedType(@Observes ProcessAnnotatedType<Object>, BeanManager) receives events for all annotated types. Consider restricting events using @WithAnnotations or a generic type with bounds.
WARN: WELD-000411: Observer method [BackedAnnotatedMethod] private org.glassfish.jersey.gf.cdi.internal.CdiComponentProvider.processAnnotatedType(@Observes ProcessAnnotatedType<Object>) receives events for all annotated types. Consider restricting events using @WithAnnotations or a generic type with bounds.
WARN: WELD-000411: Observer method [BackedAnnotatedMethod] public org.glassfish.jms.injection.JMSCDIExtension.processAnnotatedType(@Observes ProcessAnnotatedType<Object>) receives events for all annotated types. Consider restricting events using @WithAnnotations or a generic type with bounds.
Info: Loading application [jee-war] at [/jee-war]
Info: jee-war was successfully deployed in 783 milliseconds.
Info: WebModule[null] ServletContext.log():Marking servlet Main as unavailable
Warning: StandardWrapperValve[Main]: Allocate exception for servlet Main
java.lang.IllegalArgumentException: Can not set main.NoteSB field main.Main.noteSB to main.Main
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:75)
at java.lang.reflect.Field.set(Field.java:758)
at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl._inject(InjectionManagerImpl.java:688)
at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.inject(InjectionManagerImpl.java:507)
at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.injectInstance(InjectionManagerImpl.java:141)
at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.injectInstance(InjectionManagerImpl.java:127)
at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.createManagedObject(InjectionManagerImpl.java:347)
at com.sun.enterprise.web.WebContainer.createServletInstance(WebContainer.java:991)
at com.sun.enterprise.web.WebModule.createServletInstance(WebModule.java:2130)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1404)
at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:1211)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:237)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
at java.lang.Thread.run(Thread.java:745)
I will appreciate any help! I've tried many tutorials and options and still can't figure out what it is all about. Digging the stack trace is just getting me crazy, I partially understand the errors but don't know what to do, please help :)
回答1:
You're missing visible accessor methods for your noteSB
field. Add the following getter and setter methods to your Main
class:
public class Main extends HttpServlet {
// all your current code here
public NoteSB getNoteSB() {
return this.noteSB;
}
public void setNoteSB(NoteSB noteSB) {
this.noteSB = noteSB;
}
}
Refer to the JavaBean specification. Specifically this passage:
7.1 Accessor methods
Properties are always accessed via method calls on their owning object. For readable properties there will be a getter method to read the property value. For writable properties there will be a setter method to allow the property value to be updated. Thus even when a script writer types in something such as “b.Label = foo” there is still a method call into the target object to set the property, and the target object has full programmatic control.
So properties need not just be simple data fields, they can actually be computed values. Updates may have various programmatic side effects. For example, changing a bean’s background color property might also cause the bean to be repainted with the new color.
For simple properties the accessor type signatures are:
void setFoo(PropertyType value); // simple setter PropertyType getFoo(); // simple getter
来源:https://stackoverflow.com/questions/28774739/java-ee-stateless-ejb-illegalargumentexception-can-not-set-field