JEE Web Application Entity Not Found Wildfly

2019-06-09 13:58发布

问题:

I am using Wildfly 10. I am trying to bind an entity to a jsf page and save it with jpa to my db.

I am getting a javax.servlet.ServletException: javax.ejb.EJBException: java.lang.IllegalArgumentException: Unknown entity: de.rupp.model.Contact$Proxy$_$$_WeldClientProxy javax.faces.webapp.FacesServlet.service(FacesServlet.java:671)

My persistence.xml in WEB-INF/classes/META-INF:

<?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="contacts">
      <!-- If you are running in a production environment, add a managed 
         data source, this example data source is just for development and testing! -->
      <!-- The datasource is deployed as WEB-INF/jsftest-ds.xml, you
         can find it in the source at src/main/webapp/WEB-INF/jsftest-ds.xml -->
      <jta-data-source>java:/ContactsDS</jta-data-source>
      <class>de.rupp.model.Contact</class>
      <properties>
         <!-- Properties for Hibernate -->
         <property name="hibernate.hbm2ddl.auto" value="update" />
         <property name="hibernate.show_sql" value="false" />
      </properties>
   </persistence-unit>
</persistence>

My Entity

@Named
@RequestScoped
@Entity
@NamedQueries({
    @NamedQuery(name=Contact.FIND_ALL, query="SELECT c FROM Contact c"),
    @NamedQuery(name=Contact.DELETE_ALL, query="DELETE FROM Contact")
})
public class Contact implements Serializable{


    public final static String FIND_ALL = "Contacts.findAll";
    public final static String DELETE_ALL = "Contacts.deleteAll";

    /**
     * 
     */
    private static final long serialVersionUID = -7050382512059267701L;

    @Id
    @GeneratedValue
    private Long id;

    private String firstName;
    private String lastName;
    private String email;
    private String phone;
    private String message;


    //getter and setter omitted for brevity 

}

My Controller

@Named
@RequestScoped
public class EingabeController implements Serializable {

    private Logger log = LoggerFactory.getLogger(EingabeController.class);

    @Inject
    private ContactsDAOBean contactsDAOBean;


    @Inject
    private Contact contact;


    public void save() {
        this.contactsDAOBean.save(this.contact);
        log.info(this.contact + " saved");
    }

}

My persistence layer works I have written an Arquillian Test for this:

@RunWith(Arquillian.class)
public class ContactsDAOTest {


     @Deployment
        public static Archive<?> createTestArchive() {
            return ShrinkWrap.create(WebArchive.class, "test.war")
                    .addClasses(Contact.class, AbstractDAO.class, AbstractDAOBean.class, ContactsDAOBean.class)
                    .addAsResource("META-INF/persistence.xml")
                    .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");

        }




     @Inject
     private ContactsDAOBean contactsDAOBean;

     @Before
     public void init() {
         contactsDAOBean.deleteAll();
     }

     @Test
     public void save() {
         Contact contact = new Contact();
         contact.setEmail("h.rupp@dzbw.de");
         contact.setFirstName("Hans");
         contact.setLastName("Rupp");
         contact.setPhone("0711 8108 276232");
         contact.setMessage("Ich will hier raus");
         contactsDAOBean.save(contact);
         List<Contact> contacts = contactsDAOBean.findAll();
         assertEquals(1, contacts.size());
     }

}

Any ideas would be greatly appreciated

------------------- edit --------------------------------------

I have refactored this page: originally the Contact entity has been bound directly to the input elements like

<h:inputText value="#{contact.firstName}"  styleClass="form-control"/>

I have changed the controller so that it produces the entity to be saved.

@Named
@RequestScoped
public class EingabeController implements Serializable {

    @Inject
    private ContactsDAOBean contactsDAOBean;

    @Named
    @Produces
    private Contact newContact;

    @PostConstruct
    public void init() {
        this.newContact = new Contact();
    }

    public String save() {
        this.contactsDAOBean.save(this.newContact);
        log.info(this.newContact + " saved");
        this.savedContact = this.newContact;
        return "data";
    }

    @Named
    @Produces
    private Contact savedContact;

}

The @Named and the @RequestScoped Annotations have been removed from the Contact eintity.

<h:inputText value="#{newContact.lastName}" styleClass="form-control" id="lastName"/>

The page works like this, the save action can be invoked without errro.

Maybe the real cause is a misunderstandig of mine how JSF and CDI are supposed to work.

I thought that in the original version - a bean which is bound to controls is instantiated when the page is rendered - the bean is filled with the values the user enters - when the save action is called the bean is injected in the controller well this might be my error in reasoning: the controller was instantiated with the page, and at that time the Contacts bean was injected, was that not the same instance like the bean bound to the controls?

I am just trying to (re-)learn JSF .... Can anybody recommend a good source which dicusses exhaustively the architecture of JSF applications? I guess I have enough books which discuss the controls etc. in isolation.

回答1:

Try to edit your entity as in the following.

@Entity
@Table(name = "nameOfTableInDatabase", catalog = "databaseName")
@NamedQueries({
    @NamedQuery(name=Contact.FIND_ALL, query="SELECT c FROM Contact c"),
    @NamedQuery(name=Contact.DELETE_ALL, query="DELETE FROM Contact")
})
public class Contact implements java.io.Serializable {

bla
bla
}