Extends com JPA

Boa noite pessoal.

Comecei a utilizar o JPA, e uma primeira dificuldade que estou tendo, é com relação a minha tabela sofrer alterações, pois ai irei gerar uma nova classe de entidade de banco de dados, e com isso perder possiveis personalizações do codigo.

Como solução descobri a notação @MappedSuperclass, e utilizei um extends, sendo assim, sempre que precisar gerar uma nova classe, minhas personalizações estarão na classe filha e regerarei a classe pai.

Isto funcionou perfeitamente com apenas uma classe, mas quando tenho relacionamentos, indenpendente do tipo do relacionamento, acontece o seguinte erro:
Exception Description: An exception was thrown while searching for persistence archives with ClassLoader: WebappClassLoader (delegate=true; repositories=WEB-INF/classes/) Internal Exception: javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.0.1.v20100213-r6600): org.eclipse.persistence.exceptions.EntityManagerSetupException Exception Description: Predeployment of PersistenceUnit [ContabilPU] failed. Internal Exception: Exception [EclipseLink-7250] (Eclipse Persistence Services - 2.0.1.v20100213-r6600): org.eclipse.persistence.exceptions.ValidationException Exception Description: [class br.contabil.model.dto.UnidadeMedidaDTO] uses a non-entity [class br.contabil.model.dto.ex.Status] as target entity in the relationship attribute [field status].

Então, não sei se esta solução que estou tentando usar é a melhor, aceito sugestões de outras formas para contornar a dificuldade, assim como soluções para o erro acima.

Grato,

Clayton Dias

olha naum entendi o q vc ker…melhor seria postar suas classes aki pra vermos, mas o q pude perceber é o seguinte, vc criou uma classe pai e herda ela para as filhas e dentro da classe pai cria vários atributos q se relacionam, mas creio q esse tipo de herança vc soh deve usar qdo tem atributos em comum pra todas as classes, tipow, ID é normal pra todas dai vc coloca o atributo na classe pai e herda pras filhas pq já vi um exemplo usando essa anotação(@MappedSuperclass) mas só tinha um atributo dentro da classe pai e que seria herdado nas outras classes …agora se naum for isso melhor se explicar direito…

Certo, vou tentar explicar melhor.

O JPA gerou para mim as classes Status e UnidadeMedida, como seguem abaixo:


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package br.contabil.model.dto.ex;

import java.io.Serializable;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;

/**
 *
 * @author Clayton
 */
@Entity
@Table(name = "status")
@NamedQueries({
    @NamedQuery(name = "Status.findAll", query = "SELECT s FROM Status s"),
    @NamedQuery(name = "Status.findByStatusId", query = "SELECT s FROM Status s WHERE s.statusId = :statusId"),
    @NamedQuery(name = "Status.findByStatusDesc", query = "SELECT s FROM Status s WHERE s.statusDesc = :statusDesc")})
public class Status implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @Column(name = "status_id", nullable = false)
    private Integer statusId;
    @Basic(optional = false)
    @Column(name = "status_desc", nullable = false, length = 30)
    private String statusDesc;
    @OneToMany(mappedBy = "status")
    private List<UnidadeMedida> unidadeMedidaList;

    public Status() {
    }

    public Status(Integer statusId) {
        this.statusId = statusId;
    }

    public Status(Integer statusId, String statusDesc) {
        this.statusId = statusId;
        this.statusDesc = statusDesc;
    }

    public Integer getStatusId() {
        return statusId;
    }

    public void setStatusId(Integer statusId) {
        this.statusId = statusId;
    }

    public String getStatusDesc() {
        return statusDesc;
    }

    public void setStatusDesc(String statusDesc) {
        this.statusDesc = statusDesc;
    }

    public List<UnidadeMedida> getUnidadeMedidaList() {
        return unidadeMedidaList;
    }

    public void setUnidadeMedidaList(List<UnidadeMedida> unidadeMedidaList) {
        this.unidadeMedidaList = unidadeMedidaList;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (statusId != null ? statusId.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 Status)) {
            return false;
        }
        Status other = (Status) object;
        if ((this.statusId == null && other.statusId != null) || (this.statusId != null && !this.statusId.equals(other.statusId))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "br.contabil.model.dto.ex.Status[statusId=" + statusId + "]";
    }

}


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package br.contabil.model.dto.ex;

import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;

/**
 *
 * @author Clayton
 */
@Entity
@Table(name = "unidade_medida")
@NamedQueries({
    @NamedQuery(name = "UnidadeMedida.findAll", query = "SELECT u FROM UnidadeMedida u"),
    @NamedQuery(name = "UnidadeMedida.findByUnidadeMedidaId", query = "SELECT u FROM UnidadeMedida u WHERE u.unidadeMedidaId = :unidadeMedidaId"),
    @NamedQuery(name = "UnidadeMedida.findByUnidadeMedidaSigla", query = "SELECT u FROM UnidadeMedida u WHERE u.unidadeMedidaSigla = :unidadeMedidaSigla"),
    @NamedQuery(name = "UnidadeMedida.findByUnidadeMedidaDesc", query = "SELECT u FROM UnidadeMedida u WHERE u.unidadeMedidaDesc = :unidadeMedidaDesc")})
public class UnidadeMedida implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "unidade_medida_id", nullable = false)
    private Integer unidadeMedidaId;
    @Basic(optional = false)
    @Column(name = "unidade_medida_sigla", nullable = false, length = 2)
    private String unidadeMedidaSigla;
    @Basic(optional = false)
    @Column(name = "unidade_medida_desc", nullable = false, length = 50)
    private String unidadeMedidaDesc;
    @JoinColumn(name = "status_id", referencedColumnName = "status_id")
    @ManyToOne
    private Status status;

    public UnidadeMedida() {
    }

    public UnidadeMedida(Integer unidadeMedidaId) {
        this.unidadeMedidaId = unidadeMedidaId;
    }

    public UnidadeMedida(Integer unidadeMedidaId, String unidadeMedidaSigla, String unidadeMedidaDesc) {
        this.unidadeMedidaId = unidadeMedidaId;
        this.unidadeMedidaSigla = unidadeMedidaSigla;
        this.unidadeMedidaDesc = unidadeMedidaDesc;
    }

    public Integer getUnidadeMedidaId() {
        return unidadeMedidaId;
    }

    public void setUnidadeMedidaId(Integer unidadeMedidaId) {
        this.unidadeMedidaId = unidadeMedidaId;
    }

    public String getUnidadeMedidaSigla() {
        return unidadeMedidaSigla;
    }

    public void setUnidadeMedidaSigla(String unidadeMedidaSigla) {
        this.unidadeMedidaSigla = unidadeMedidaSigla;
    }

    public String getUnidadeMedidaDesc() {
        return unidadeMedidaDesc;
    }

    public void setUnidadeMedidaDesc(String unidadeMedidaDesc) {
        this.unidadeMedidaDesc = unidadeMedidaDesc;
    }

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (unidadeMedidaId != null ? unidadeMedidaId.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 UnidadeMedida)) {
            return false;
        }
        UnidadeMedida other = (UnidadeMedida) object;
        if ((this.unidadeMedidaId == null && other.unidadeMedidaId != null) || (this.unidadeMedidaId != null && !this.unidadeMedidaId.equals(other.unidadeMedidaId))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "br.contabil.model.dto.ex.UnidadeMedida[unidadeMedidaId=" + unidadeMedidaId + "]";
    }

}

O que acontece, é que preciso fazer algumas modificações nas classes acima. E como vou proceder se o banco sofrer alguma alteração? Quando eu re-gerar a classe, irei perder as modificações que fiz.
Ai vem a primeira pergunta: Como vocês tratam isto?

Como solução, tentei fazer o seguinte:

Alterei as classes Status e UnidadeMedida:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package br.contabil.model.dto.ex;

import java.io.Serializable;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.OneToMany;

/**
 *
 * @author Clayton
 */
@MappedSuperclass
public class Status implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @Column(name = "status_id", nullable = false)
    private Integer statusId;
    @Basic(optional = false)
    @Column(name = "status_desc", nullable = false, length = 30)
    private String statusDesc;
    @OneToMany(mappedBy = "status")
    private List<UnidadeMedida> unidadeMedidaList;

    public Status() {
    }

    public Status(Integer statusId) {
        this.statusId = statusId;
    }

    public Status(Integer statusId, String statusDesc) {
        this.statusId = statusId;
        this.statusDesc = statusDesc;
    }

    public Integer getStatusId() {
        return statusId;
    }

    public void setStatusId(Integer statusId) {
        this.statusId = statusId;
    }

    public String getStatusDesc() {
        return statusDesc;
    }

    public void setStatusDesc(String statusDesc) {
        this.statusDesc = statusDesc;
    }

    public List<UnidadeMedida> getUnidadeMedidaList() {
        return unidadeMedidaList;
    }

    public void setUnidadeMedidaList(List<UnidadeMedida> unidadeMedidaList) {
        this.unidadeMedidaList = unidadeMedidaList;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (statusId != null ? statusId.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 Status)) {
            return false;
        }
        Status other = (Status) object;
        if ((this.statusId == null && other.statusId != null) || (this.statusId != null && !this.statusId.equals(other.statusId))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "br.contabil.model.dto.ex.Status[statusId=" + statusId + "]";
    }

}


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package br.contabil.model.dto.ex;

import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;

/**
 *
 * @author Clayton
 */
@MappedSuperclass
public class UnidadeMedida implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "unidade_medida_id", nullable = false)
    private Integer unidadeMedidaId;
    @Basic(optional = false)
    @Column(name = "unidade_medida_sigla", nullable = false, length = 2)
    private String unidadeMedidaSigla;
    @Basic(optional = false)
    @Column(name = "unidade_medida_desc", nullable = false, length = 50)
    private String unidadeMedidaDesc;
    @JoinColumn(name = "status_id", referencedColumnName = "status_id")
    @ManyToOne
    private Status status;

    public UnidadeMedida() {
    }

    public UnidadeMedida(Integer unidadeMedidaId) {
        this.unidadeMedidaId = unidadeMedidaId;
    }

    public UnidadeMedida(Integer unidadeMedidaId, String unidadeMedidaSigla, String unidadeMedidaDesc) {
        this.unidadeMedidaId = unidadeMedidaId;
        this.unidadeMedidaSigla = unidadeMedidaSigla;
        this.unidadeMedidaDesc = unidadeMedidaDesc;
    }

    public Integer getUnidadeMedidaId() {
        return unidadeMedidaId;
    }

    public void setUnidadeMedidaId(Integer unidadeMedidaId) {
        this.unidadeMedidaId = unidadeMedidaId;
    }

    public String getUnidadeMedidaSigla() {
        return unidadeMedidaSigla;
    }

    public void setUnidadeMedidaSigla(String unidadeMedidaSigla) {
        this.unidadeMedidaSigla = unidadeMedidaSigla;
    }

    public String getUnidadeMedidaDesc() {
        return unidadeMedidaDesc;
    }

    public void setUnidadeMedidaDesc(String unidadeMedidaDesc) {
        this.unidadeMedidaDesc = unidadeMedidaDesc;
    }

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (unidadeMedidaId != null ? unidadeMedidaId.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 UnidadeMedida)) {
            return false;
        }
        UnidadeMedida other = (UnidadeMedida) object;
        if ((this.unidadeMedidaId == null && other.unidadeMedidaId != null) || (this.unidadeMedidaId != null && !this.unidadeMedidaId.equals(other.unidadeMedidaId))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "br.contabil.model.dto.ex.UnidadeMedida[unidadeMedidaId=" + unidadeMedidaId + "]";
    }

}

E criei novas classes que são suas filhas:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package br.contabil.model.dto;

import br.contabil.model.dto.ex.Status;
import javax.persistence.Entity;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;

/**
 *
 * @author Clayton
 */
@Entity
@Table(name = "status")
@NamedQueries({
    @NamedQuery(name = "Status.findAll", query = "SELECT s FROM Status s"),
    @NamedQuery(name = "Status.findByStatusId", query = "SELECT s FROM Status s WHERE s.statusId = :statusId"),
    @NamedQuery(name = "Status.findByStatusDesc", query = "SELECT s FROM Status s WHERE s.statusDesc = :statusDesc")})
public class StatusDTO extends Status{

}

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package br.contabil.model.dto;

import br.contabil.model.dto.ex.UnidadeMedida;
import javax.persistence.Entity;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;

/**
 *
 * @author Clayton
 */
@Entity
@Table(name = "unidade_medida")
@NamedQueries({
    @NamedQuery(name = "UnidadeMedida.findAll", query = "SELECT u FROM UnidadeMedida u"),
    @NamedQuery(name = "UnidadeMedida.findByUnidadeMedidaId", query = "SELECT u FROM UnidadeMedida u WHERE u.unidadeMedidaId = :unidadeMedidaId"),
    @NamedQuery(name = "UnidadeMedida.findByUnidadeMedidaSigla", query = "SELECT u FROM UnidadeMedida u WHERE u.unidadeMedidaSigla = :unidadeMedidaSigla"),
    @NamedQuery(name = "UnidadeMedida.findByUnidadeMedidaDesc", query = "SELECT u FROM UnidadeMedida u WHERE u.unidadeMedidaDesc = :unidadeMedidaDesc")})
public class UnidadeMedidaDTO extends UnidadeMedida{

}

Quando vou personalizar o codigo, altero as filhas, e utilizo somente instancias das classes filhas, sendo assim se eu precisar por qualquer motivo regerar o codigo da classe pai, não perco as personalizações. No entanto quando vou utilizar tenho o erro que publiquei no primeiro post. Ficou claro agora minha dificuldade?

Clayton Dias

Alguem?