No meu sistema tenho as seguintes classes:
Porte:
@Entity
@Table(name = "porte", catalog = "dbsghu", schema = "dbsghu")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Porte.findAll", query = "SELECT p FROM Porte p"),
@NamedQuery(name = "Porte.findByNrPorte", query = "SELECT p FROM Porte p WHERE p.nrPorte = :nrPorte")})
public class Porte implements Serializable {
private static final long serialVersionUID = 1L;
public static final String TABLE_NAME = "porte";
/**
* ID do Porte. Numeração gerada automaticamente pelo banco de dados.
* <br>Coluna: <tt>nr_porte</tt>.
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "nr_porte")
private Short nrPorte;
/**
* Opção utilizada pelo sistema para informar ao usuário que o registro já
* está sendo utilizado. <br>Coluna: <tt>bl_ocupado</tt>.
*/
@Column(name = "bl_ocupado")
private boolean blOcupado;
/**
* Grupo do Porte. Relacionamento com a classe
* <tt>entidades.PorteGrupo</tt>.
*/
@ManyToOne(optional = false)
@JoinColumn(name = "nr_grpporte", referencedColumnName = "nr_grupoporte", unique = true)
private PorteGrupo nrGrpporte;
/**
* Subgrupo do Porte. Relacionamento com a classe
* <tt>entidades.PorteSubgrupo</tt>.
*/
@ManyToOne(optional = false)
@JoinColumn(name = "nr_subgrpporte", referencedColumnName = "nr_subgrpporte", unique = true)
private PorteSubgrupo nrSubgrpporte;
/**
* Lista de Valores do Porte. Relacionamento com a classe
* <tt>entidades.PorteValores</tt>.
*/
@OneToMany(cascade = CascadeType.PERSIST, mappedBy = "porte", fetch = FetchType.EAGER)
@NotFound(action = NotFoundAction.IGNORE)
private List<PorteValores> porteValoresList = null;
/**
* Porte Anestésico. Lista de Portes Anestésicos que estão vinculados a este
* Porte. Relacionamento com a classe
* <tt>entidades.PorteAnestesico</tt>.
*/
@OneToMany(mappedBy = "nrPorte", fetch = FetchType.LAZY, orphanRemoval = true)
@NotFound(action = NotFoundAction.IGNORE)
private List<PorteAnestesico> porteAnestesicoList = null;
/**
* Valores de Procedimentos. Lista dos Valores dos Procedimentos que possuem
* este Porte. Relacionamento com a classe <tt>ProcedimentoValores</tt>.
*/
@OneToMany(mappedBy = "nrPorte", fetch = FetchType.LAZY, orphanRemoval = true)
@NotFound(action = NotFoundAction.IGNORE)
private List<ProcedimentoValores> procedimentoValoresList = null;
/**
* Construtor da Classe.
*/
public Porte() {
}
...
}
PorteValores:
@Entity
@Table(name = "porte_valores", catalog = "dbsghu", schema = "dbsghu")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "PorteValores.findAll", query = "SELECT p FROM PorteValores p"),
@NamedQuery(name = "PorteValores.findByNrPorte", query = "SELECT p FROM PorteValores p WHERE p.porteValoresPK.nrPorte = :nrPorte"),
@NamedQuery(name = "PorteValores.findByDtVigencia", query = "SELECT p FROM PorteValores p WHERE p.porteValoresPK.dtVigencia = :dtVigencia")})
public class PorteValores implements Serializable {
private static final long serialVersionUID = 1L;
public static final String TABLE_NAME = "porte_valores";
/**
* Objeto de relacionamento com a classe Porte.
*/
@EmbeddedId
protected PorteValoresPK porteValoresPK;
/**
* Valor do Porte. <p>Coluna: <tt>vl_porte</tt>
*/
// @Max(value=?) @Min(value=?)//if you know range of your decimal fields consider using these annotations to enforce field validation
@Basic(optional = false)
@Column(name = "vl_porte")
private BigDecimal vlPorte;
/**
* ID do Porte. Campo utilizado pelo banco de dados para realizar o
* relacionamento com seus Valores. <p>Coluna: <tt>nr_prestador</tt>
*/
@ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "nr_porte", referencedColumnName = "nr_porte", insertable = false, updatable = false, nullable = false)
private Porte porte;
/**
* Construtor da Classe.
*/
public PorteValores() {
}
...
}
PorteValoresPK:
@Embeddable
public class PorteValoresPK implements Serializable {
/**
* ID do Porte. Numeração gerada automaticamente pelo banco de dados.
* <br>Coluna: <tt>nr_porte</tt>
*/
@Basic(optional = false)
@Column(name = "nr_porte")
private short nrPorte;
/**
* Data de Vigência do Porte.
*/
@Basic(optional = false)
@Column(name = "dt_vigencia")
@Temporal(TemporalType.DATE)
private Date dtVigencia;
/**
* Construtor da Classe.
*/
public PorteValoresPK() {
}
...
}
Pois bem, quando tento realizar um insert em cascata o log4j me retorna o seguinte erro.
Internal Exception: org.postgresql.util.PSQLException: ERROR: insert or update on table "porte_valores" violates foreign key constraint "fk_portevalores1"
Detalhe: Key (nr_porte)=(0) is not present in table "porte".
Error Code: 0
Call: INSERT INTO dbsghu.dbsghu.porte_valores (vl_porte, dt_vigencia, nr_porte) VALUES (?, ?, ?)
bind => [3 parameters bound]
Query: InsertObjectQuery(entidades.PorteValores[ porteValoresPK=entidades.PorteValoresPK[ nrPorte=0, dtVigencia=2003-08-01 ] ])
Então como faço o insert em cascata de forma que o JPA alimente automaticamente o campo nrPorte da classe PorteValores?
Sei que o erro refere-se exatamente a isso, mas se é um insert em cascata por que o JPA não está passando o valor automaticamente?
É algum erro nas minhas classes?
Desde já agradeço a ajuda.