EJB не удалось обновить модель данных - PullRequest
2 голосов
/ 12 июня 2010

Вот мой EJB

@Entity
@Table(name = "modelos")
@NamedQueries({
    @NamedQuery(name = "Modelos.findAll", query = "SELECT m FROM Modelos m"),
    @NamedQuery(name = "Modelos.findById", query = "SELECT m FROM Modelos m WHERE m.id = :id"),
    @NamedQuery(name = "Modelos.findByDescripcion", query = "SELECT m FROM Modelos m WHERE m.descripcion = :descripcion")})
public class Modelos implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;
    @Basic(optional = false)
    @Column(name = "descripcion")
    private String descripcion;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "idModelo")
    private Collection<Produtos> produtosCollection;
    @JoinColumn(name = "id_marca", referencedColumnName = "id")
    @ManyToOne(optional = false)
    private Marcas idMarca;

    public Modelos() {
    }

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

    public Modelos(Integer id, String descripcion) {
        this.id = id;
        this.descripcion = descripcion;
    }

    public Modelos(Integer id, Marcas idMarca) {
        this.id = id;
        this.idMarca = idMarca;
    }

    public Integer getId() {
        return id;
    }

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

    public String getDescripcion() {
        return descripcion;
    }

    public void setDescripcion(String descripcion) {
        this.descripcion = descripcion;
    }

    public Collection<Produtos> getProdutosCollection() {
        return produtosCollection;
    }

    public void setProdutosCollection(Collection<Produtos> produtosCollection) {
        this.produtosCollection = produtosCollection;
    }

    public Marcas getIdMarca() {
        return idMarca;
    }

    public void setIdMarca(Marcas idMarca) {
        this.idMarca = idMarca;
    }

    @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 Modelos)) {
            return false;
        }
        Modelos other = (Modelos) 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 "" + descripcion + "";
    }

}

И способ доступа из Modelosfacade

public List<Modelos> findByMarcas(Marcas idMarca){
    return em.createQuery("SELECT id, descripcion FROM Modelos WHERE idMarca = "+idMarca.getId()+"").getResultList();
}

И метод вызова из контроллера

public String createByMarcas() {
    //recreateModel();
    items = new ListDataModel(ejbFacade.findByMarcas(current.getIdMarca()));
    updateCurrentItem();
    System.out.println(current.getIdMarca());
    return "List";
}

У меня нетпонять, почему я продолжаю попадать в исключение EJB.

Caused by: javax.ejb.EJBException
 at com.sun.ejb.containers.BaseContainer.processSystemException(BaseContainer.java:5070)
 at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:4968)
 at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4756)
 at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1955)
 at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1906)
 at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:198)
 at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:84)
 at $Proxy347.findByMarcas(Unknown Source)
 at controladores.__EJB31_Generated__ModelosFacade__Intf____Bean__.findByMarcas(Unknown Source)

1 Ответ

1 голос
/ 12 июня 2010

На самом деле, я почти уверен, что в журналах сервера есть больше полезных следов.Но в любом случае у меня есть несколько замечаний:

Прежде всего, id для Marca не является атрибутом Modelos, поэтому ваш запрос неверен, вам нужно либо передать экземпляр, либоMarcas или для навигации по ассоциации, если вы передаете id (вам нужно подумать об объекте и ассоциации при использовании JPA).

Во-вторых, то, как вы выполняете запрос, неверно, вам следуетпараметризовать его.

В-третьих, при использовании проекций SQL вы получите Object[] (или List<Object[]>, если имеется несколько результатов), а не строго типизированный результат, если вы не используете выражение конструктора SELECT NEW.

Подводя итог, должно работать следующее:

public List<Object[]> findByMarcas(Marcas marcas){
    Query q = em.createQuery("SELECT m.id, m.descripcion FROM Modelos m WHERE m.idMarca = :marcas");
    q.setParameter("marcas", marcas);
    return q.getResultList();
}

Или, если вы передаете идентификатор в качестве параметра запроса (но приведенный выше запрос вполне подходит):

public List<Object[]> findByMarcas(Marcas marcas){
    Query q = em.createQuery("SELECT m.id, m.descripcion FROM Modelos m WHERE m.idMarca.id = :idMarca");
    q.setParameter("idMarca", marcas.getId());
    return q.getResultList();
}

Но я бы не использовал проекции или использовал выражение конструктора SELECT NEW:

public List<Modelos> findByMarcas(Marcas marcas){
    Query q = em.createQuery("SELECT m FROM Modelos m WHERE m.idMarca.id = :idMarca");
    q.setParameter("idMarca", marcas.getId());
    return q.getResultList();
}

или (при условии, что Modelos имеет соответствующий конструктор):

public List<Modelos> findByMarcas(Marcas marcas){
    Query q = em.createQuery("SELECT NEW com.acme.Modelos(m.id, m.descripcion) FROM Modelos m WHERE m.idMarca.id = :idMarca");
    q.setParameter("idMarca", marcas.getId());
    return q.getResultList();
}

И вообще, я бы использовал именованный запрос, например:

@NamedQuery(
    name="Modelos.findByMarcas",
    query="SELECT m FROM Modelos m WHERE m.idMarca = :marcas"
)

и использовал бы:

public List<Modelos> findByMarcas(Marcas marcas){
    Query q = em.createNamedQuery("Modelos.findByMarcas");
    q.setParameter("marcas", marcas);
    return q.getResultList();
}

Кстати, я бы переименовал idMarca в marcas наModelos сущность, idMarca вводит в заблуждение:

@ManyToOne(optional = false)
private Marcas marcas;
...