Object: entity.ENTITY [id = null] не является известным типом сущности - PullRequest
0 голосов
/ 02 февраля 2012

Этот пост похож на тот, который я видел ранее об этом исключении, но я совершенно потерян. Мне еще предстоит сохранить объект в базе данных с использованием JPA, хотя я читал из таблиц, используя его без проблем. Моя установка - Netbeans 7.1 с использованием Glassfish 3.1.1, EclipseLink - мой поставщик постоянных данных. У меня очень простой сценарий, в котором я просто хочу проверить запись имени и возраста людей в базу данных и автоматическое увеличение идентификатора. Это база данных MySql с полями: Id, FirstName и Age. Вот мой код:

Веб-сервлет для получения имени и возраста из HTML-формы:

    @Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

    String userPath = request.getServletPath();

    if(userPath.equals("/addUser")){

        //get request parameters from form
        String name = request.getParameter("name");
        String age = request.getParameter("age");

        //set request attributes to be used by forwarded page
        request.setAttribute("name", name);
        request.setAttribute("age", age);

        //create manager class to add person to database
        Manager manager = new Manager();
        manager.addPerson(name, age);

        userPath = "/result";
    }

    // use RequestDispatcher to forward request internally
    String url = "/WEB-INF/view" + userPath + ".jsp";

    try {
        request.getRequestDispatcher(url).forward(request, response);
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

Класс менеджера, который принимает имя и возраст, создает объект person и сохраняет его.

public class Manager {

private static final String PERSISTENCE_UNIT_NAME = "FormPU";
private static EntityManagerFactory factory;

public Manager() {
}

public void addPerson(String name, String age) {

    factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
    EntityManager em = factory.createEntityManager();

    Persons persons = new Persons();
    persons.setName(name);
    persons.setAge(age);

    em.getTransaction().begin();
    em.persist(persons);
    em.getTransaction().commit();
    em.close();
}
}

Лица юридического лица:

    /**
    *
    * @author esmiala
    */
    @Entity
    @Table(name = "persons")
    @XmlRootElement
    @NamedQueries({
      @NamedQuery(name = "Persons.findAll", query = "SELECT p FROM Persons p"),
      @NamedQuery(name = "Persons.findById", query = "SELECT p FROM Persons p WHERE  
      p.id = :id"),
      @NamedQuery(name = "Persons.findByFirstName", query = "SELECT p FROM Persons p 
      WHERE p.firstName = :firstName"),
      @NamedQuery(name = "Persons.findByAge", query = "SELECT p FROM Persons p WHERE 
      p.age = :age")})
public class Persons implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@NotNull
@Column(name = "Id")
private Integer id;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 255)
@Column(name = "FirstName")
private String firstName;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 255)
@Column(name = "Age")
private String age;

public Persons() {
}

public Persons(Integer id) {
    this.id = id;
}

public Persons(Integer id, String firstName, String age) {
    this.id = id;
    this.firstName = firstName;
    this.age = age;
}

public Integer getId() {
    return id;
}

public void setId(Integer id) {
    this.id = id;
}

public String getFirstName() {
    return firstName;
}

public void setFirstName(String firstName) {
    this.firstName = firstName;
}

public String getAge() {
    return age;
}

public void setAge(String age) {
    this.age = age;
}

@Override
public int hashCode() {
    int hash = 0;
    hash += (id != null ? id.hashCode() : 0);
    return hash;
}

@Override
public boolean equals(Object object) {
    // TODO: Warning - this method won't work in the case the id fields are not set
    if (!(object instanceof Persons)) {
        return false;
    }
    Persons other = (Persons) 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 "entity.Persons[ id=" + id + " ]";
}

}

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="FormPU" transaction-type="JTA">
     <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
     <jta-data-source>jdbc/form</jta-data-source>
     <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties/>
    </persistence-unit>
    </persistence>

Примечание. Я также попытался установить для тега exclude-unlisted-classes значение true и отдельно перечислить класс, но это тоже не сработало.

Исключение:

    WARNING: StandardWrapperValve[Controller]: PWC1406: Servlet.service() for servlet  
    Controller threw exception
    java.lang.IllegalArgumentException: Object: entity.persons[ id=null ] is not a   
    known entity type.
atorg.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObject
    ForPersist(UnitOfWorkImpl.java:4141)
atorg.eclipse.persistence.internal.jpa.EntityManagerImpl.   
    persist(EntityManagerImpl.java:368)
at manager.Manager.addPerson(Manager.java:36)
at controller.Controller.doPost(Controller.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:754)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523)

... и так далее. Любая помощь будет принята с благодарностью!

Ответы [ 3 ]

1 голос
/ 02 февраля 2012

Итак, вы говорите, что можете читать класс нормально, но получаете сообщение об ошибке при сохранении нового экземпляра?

Можете ли вы обновить прочитанный объект?

Кажется, у вас какой-то типвопроса загрузчика классов.Каким-то образом у вас есть класс на вашем classpath дважды, или у вас есть два разных загрузчика классов.Объект, который вы передаете для сохранения, получен из загрузчика классов, отличного от того, который использует JPA.Вы можете проверить загрузчик классов того, что было прочитано, и объекта, который был сохранен, чтобы увидеть, как они отличаются.

Вы повторно развернули свое приложение, или горячее развертывание?Работает ли это, если вы правильно выключили / перезапустили сервер.Перед повторным развертыванием убедитесь, что вы закрываете свой старый EntityManagerFactory.

1 голос
/ 02 февраля 2012

<exclude-unlisted-classes> работает не так, как вы ожидаете - само присутствие этого элемента в persistence.xml отключает автоматическое обнаружение @Entity классов, независимо от того, что внутри него.

Кроме того, @Entity(name="persons"), вероятно, не то, что вы хотите, используйте @Entity @Table (name="persons") вместо.

0 голосов
/ 02 февраля 2012

Что касается конкретной проблемы, попробуйте посмотреть, поможет ли эта ссылка .

В любом случае, способ создания EntityManager не безопасен для потоков.

Вы можете увидеть здесь почему. Или, что еще лучше, вы можете использовать мастер NetBeans для создания классов контроллера JPA из классов сущностей и посмотреть, как он внедряет EntityManager:

@PersistenceContext
private EntityManager em;

Смотрите также, что классы контроллеров (эквивалент вашего менеджера POJO) имеют аннотацию Stateless. Это потому, что вы можете безопасно внедрить EJB (в данном случае EntityManager) только в объект, жизненный цикл которого управляется веб-контейнером (см. здесь для получения дополнительной информации о доступе к корпоративным компонентам).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...