I am working on an application that requires data from faculties and careers to be saved and I have created the following entities:
Faculty
@Entity
@Table(name = "uc_facultades", schema = "uc")
@SequenceGenerator(name = "Facultades_id_seq", sequenceName = "uc.uc_facultades_id_seq", allocationSize = 1)
public class Facultad implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "Facultades_id_seq")
@Column(name = "id")
private Integer id;
@NotNull
@Size(max = 70)
@Column(name = "nombre")
private String nombre;
@NotNull
@Column(name = "estado", columnDefinition = "boolean default true")
private Boolean estado;
@OneToMany(mappedBy="facultad", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<Carrera> carreras;
//Getters y Setters
public void addCarrera(Carrera carrera){
carreras.add(carrera);
if(carrera.getFacultad() != this){
carrera.setFacultad(this);
}
}
}
Carrera
@Entity
@Table(name="uc_carreras", schema="uc")
@SequenceGenerator(name = "Carreras_id_seq", sequenceName = "uc.uc_carreras_id_seq", allocationSize = 1)
public class Carrera implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="Carreras_id_seq")
@Column(name="id")
private Integer id;
@NotNull
@Size(max=80)
@Column(name="nombre")
private String nombre;
@NotNull
@Column(name="estado", columnDefinition="boolean default true")
private boolean estado = true;
@ManyToOne(fetch = FetchType.LAZY, optional=false, cascade = CascadeType.ALL, targetEntity = Facultad.class)
@JoinColumn(name="idfacultad", referencedColumnName="id", nullable = false, insertable = false)
private Facultad facultad;
@ManyToMany(cascade = CascadeType.ALL, targetEntity = Pensum.class)
@JoinTable(name="uc.uc_pensum_carrera",
joinColumns=@JoinColumn(name="idcarrera", referencedColumnName="id", nullable = false),
inverseJoinColumns=@JoinColumn(name="idpensum", referencedColumnName="id", nullable = false))
@OrderBy(value = "año DESC")
private List<Pensum> pensums;
//Getters y Setters
}
This code is with which I register a new career:
@Override
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void guardarCarrera(CarrerasDTO carreraDTO) {
LOG.info("[CarrerasService][guardarCarrera]");
try {
Facultad facultad = em.find(Facultad.class, carreraDTO.getFacultad().getId());//Se extrae la entity
Carrera carrera = new Carrera();
carrera.setNombre(carreraDTO.getNombre());
carrera.setFacultad(facultad);
carrera.setEstado(Boolean.TRUE);
carreraDTO.getPensums().stream().forEach(pensum -> {
carrera.addPensum(pensum);
});
em.persist(carrera);
em.flush();
} catch (Exception e) {
LOG.log(Level.SEVERE, "[CarrerasService][guardarCarrera] Excepcion -> {0}", e.getMessage());
}
}
If I try to persist with CascadeType.PERSIST or CascadeTYpe.ALLme throws the following exception:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.7.0.v20170811-d680af5): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: llave duplicada viola restricción de unicidad «pk_facultad»
If I use the CascadeType.MERGE it throws me the following exception:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.7.0.v20170811-d680af5): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: el valor null para la columna «idfacultad» viola la restricción not null
I have been researching and correcting the entities and the method for several days but nothing works. I hope you can help me.
NOTE: For the development of this I am using:
- Java EE 7 (Web Application)
- JPA 2.1 with EclipseLink
- EJB Lite 3.2