0

I have a problem when I do a query to my repo with Page page = entityRepository.findAll(pageable). So, I don't know why when hibernate build the query this do it like asignatura_id and profesor_id in the entity asignaturaProfesor if its id is a object from AsignaturaProfesorId entity and this fields are id_profesor and id_asignatura

I get this error:

Hibernate: select profesor0_.id as id1_8_, profesor0_.categoria as categori2_8_, profesor0_.cod_profesor as cod_prof3_8_, profesor0_.email as email4_8_, profesor0_.login as login5_8_, profesor0_.nombre as nombre6_8_, profesor0_.num_creditos_impartir as num_cred7_8_, profesor0_.primer_apellido as primer_a8_8_, profesor0_.prioridad as priorida9_8_, profesor0_.segundo_apellido as segundo10_8_, profesor0_.usu_alta as usu_alt11_8_ from profesor profesor0_

> Hibernate: select asignatura0_.profesor_id as profesor4_1_0_, asignatura0_.fecha_seleccion as fecha_se1_1_0_, asignatura0_.asignatura_id as asignatu3_1_0_, asignatura0_.fecha_seleccion as fecha_se1_1_1_, asignatura0_.asignatura_id as asignatu3_1_1_, asignatura0_.profesor_id as profesor4_1_1_, asignatura0_.num_creditos as num_cred2_1_1_ from asignatura_profesor asignatura0_ where asignatura0_.profesor_id=?

WARN 19148 --- [ XNIO-2 task-8] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1054, SQLState: 42S22 ERROR 19148 --- [ XNIO-2 task-8] o.h.engine.jdbc.spi.SqlExceptionHelper : Unknown column 'asignatura0_.profesor_id' in 'field list'

This is my database schema:

CREATE TABLE asignatura_profesor (
id_profesor bigint(20) NOT NULL,
id_asignatura bigint(20) NOT NULL,
fecha_seleccion timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE  CURRENT_TIMESTAMP,
num_creditos bigint(20) NOT NULL,
PRIMARY KEY (id_asignatura,id_profesor,fecha_seleccion),
KEY FK_PROFESORES_ASIGNATURA_PROFESORES_01 (id_profesor),
CONSTRAINT FK_PROFESORES_ASIGNATURA_ASIGNATURAS_02 FOREIGN KEY (id_asignatura) REFERENCES asignatura (id),
CONSTRAINT FK_PROFESORES_ASIGNATURA_PROFESORES_01 FOREIGN KEY (id_profesor) REFERENCES profesor (id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1


CREATE TABLE profesor (
id bigint(20) NOT NULL AUTO_INCREMENT,
nombre varchar(255) NOT NULL,
primer_apellido varchar(255) NOT NULL,
segundo_apellido varchar(255) NOT NULL,
cod_profesor int(11) NOT NULL,
email varchar(255) NOT NULL,
categoria` varchar(255) NOT NULL,
num_creditos_impartir int(11) DEFAULT NULL,
prioridad int(11) NOT NULL,
usu_alta varchar(255) NOT NULL,
login varchar(50) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1

CREATE TABLE asignatura (
id bigint(20) NOT NULL AUTO_INCREMENT,
nombre varchar(255) NOT NULL,
plan varchar(255) NOT NULL,
titulacion varchar(255) NOT NULL,
creditos int(11) NOT NULL,
num_grupos int(11) DEFAULT NULL,
creditos_teoricos int(11) NOT NULL,
creditos_practicas int(11) NOT NULL,
num_grupos_teoricos int(11) DEFAULT NULL,
num_grupos_practicas int(11) DEFAULT NULL,
usu_alta varchar(255) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1

This is my code:

Profesor.java

@Entity
@Table(name = "profesor")
public class Profesor implements Serializable ,  Comparable<Profesor>{

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@NotNull
@Column(name = "nombre", nullable = false)
private String nombre;

@NotNull
@Column(name = "primer_apellido", nullable = false)
private String primerApellido;

@NotNull
@Column(name = "segundo_apellido", nullable = false)
private String segundoApellido;

@NotNull
@Max(value = 3)
@Column(name = "cod_profesor", nullable = false)
private Integer codProfesor;

@NotNull
@Column(name = "email", nullable = false)
private String email;

@NotNull
@Column(name = "categoria", nullable = false)
private String categoria;

@Column(name = "num_creditos_impartir")
private Integer numCreditosImpartir;

@NotNull
@Max(value = 2)
@Column(name = "prioridad", nullable = false)
private Integer prioridad;

@NotNull
@Column(name = "usu_alta", nullable = false)
private String usuAlta;

@OneToMany(
    mappedBy = "profesor",
    cascade = CascadeType.ALL,
    fetch=FetchType.EAGER,
    orphanRemoval = true
)
private List<AsignaturaProfesor> asignaturas = new ArrayList<>();

@NotNull
@Column(name = "login", nullable = false)
private String login;

public Profesor() {}

public List<AsignaturaProfesor> getAsignaturas() {
    return asignaturas;
}

public void setAsignaturas(List<AsignaturaProfesor> asignaturas) {
    this.asignaturas = asignaturas;
}

//GETTER AND SETTERS

public void addAsignatura(Asignatura asignatura, long num_creditos_seleccion ) {
    AsignaturaProfesor asignaturaProfesor = new AsignaturaProfesor(this, asignatura, num_creditos_seleccion);
    asignaturas.add(asignaturaProfesor);
    asignatura.getProfesors().add(asignaturaProfesor);
}

public void removeAsignatura(Asignatura asignatura) {
    for (Iterator<AsignaturaProfesor> iterator = asignaturas.iterator();
         iterator.hasNext(); ) {
        AsignaturaProfesor asignaturaProfesor = iterator.next();

        if (asignaturaProfesor.getProfesor().equals(this) &&
            asignaturaProfesor.getAsignatura().equals(asignatura)) {
            iterator.remove();
            asignaturaProfesor.getAsignatura().getProfesors().remove(asignaturaProfesor);
            asignaturaProfesor.setProfesor(null);
            asignaturaProfesor.setAsignatura(null);
        }
    }
}

@Override
public boolean equals(Object o) {
    if (this == o) {
        return true;
    }
    if (o == null || getClass() != o.getClass()) {
        return false;
    }
    Profesor profesor = (Profesor) o;
    if (profesor.id == null || id == null) {
        return false;
    }
    return Objects.equals(id, profesor.id);
}

@Override
public int hashCode() {
    return Objects.hashCode(id);
}

public int compareTo(Profesor o) {
    if (prioridad < o.prioridad) {
        return -1;
    }
    if (prioridad > o.prioridad) {
        return 1;
    }
    return 0;
}
}

AsignaturaProfesorId.java

@Entity
@Table(name="asignatura_profesor")

public class AsignaturaProfesor implements Serializable {

private static final long serialVersionUID = 1L;

@EmbeddedId
public AsignaturaProfesorId profasigpk;

@NotNull
@Column (name = "num_creditos")
private  Long num_creditos;

@ManyToOne(fetch = FetchType.LAZY)
@MapsId("id_profesor")
private Profesor profesor;

@ManyToOne(fetch = FetchType.LAZY)
@MapsId("id_asignatura")
private Asignatura asignatura;

public AsignaturaProfesor() {
}

public AsignaturaProfesor(AsignaturaProfesorId profAsigpk, Long num_creditos) {
    this.profasigpk = profAsigpk;
    this.num_creditos = num_creditos;
}

public AsignaturaProfesor(Profesor profesor, Asignatura asignatura, long num_creditos){
    this.profesor = profesor;
    this.asignatura = asignatura;
    this.num_creditos = num_creditos;
}

//GETTER AND SETTER

@Override
public boolean equals(Object o) {
    if (this == o) return true;

    if (o == null || getClass() != o.getClass())
        return false;

    AsignaturaProfesor that = (AsignaturaProfesor) o;
    return Objects.equals(profesor, that.asignatura) &&
        Objects.equals(asignatura, that.profesor);
}

@Override
public int hashCode() {
    return Objects.hash(profesor, asignatura);
}

@Override
public String toString() {
    return "AsignaturaProfesor{" +
        "profAsigpk=" + profasigpk +
        '}';
}

}

ProfesorAsignatura.java

@Entity
@Table(name="asignatura_profesor")

public class AsignaturaProfesor implements Serializable {

private static final long serialVersionUID = 1L;

@EmbeddedId
public AsignaturaProfesorId profasigpk;

@NotNull
@Column (name = "num_creditos")
private  Long num_creditos;

@ManyToOne(fetch = FetchType.LAZY)
@MapsId("id_profesor")
private Profesor profesor;

@ManyToOne(fetch = FetchType.LAZY)
@MapsId("id_asignatura")
private Asignatura asignatura;



public AsignaturaProfesor() {
}

public AsignaturaProfesor(AsignaturaProfesorId profAsigpk, Long num_creditos) {
    this.profasigpk = profAsigpk;
    this.num_creditos = num_creditos;
}

public AsignaturaProfesor(Profesor profesor, Asignatura asignatura, long num_creditos){
    this.profesor = profesor;
    this.asignatura = asignatura;
    this.num_creditos = num_creditos;
}

public AsignaturaProfesorId getProfAsigpk() {
    return profasigpk;
}

public void setProfAsigpk(AsignaturaProfesorId profAsigpk) {
    this.profasigpk = profAsigpk;
}

public Long getNum_creditos() {
    return num_creditos;
}

public void setNum_creditos(Long num_creditos) {
    this.num_creditos = num_creditos;
}

public Profesor getProfesor() {
    return profesor;
}

public void setProfesor(Profesor profesor) {
    this.profesor = profesor;
}

public Asignatura getAsignatura() {
    return asignatura;
}

public void setAsignatura(Asignatura asignatura) {
    this.asignatura = asignatura;
}

@Override
public boolean equals(Object o) {
    if (this == o) return true;

    if (o == null || getClass() != o.getClass())
        return false;

    AsignaturaProfesor that = (AsignaturaProfesor) o;
    return Objects.equals(profesor, that.asignatura) &&
        Objects.equals(asignatura, that.profesor);
}

@Override
public int hashCode() {
    return Objects.hash(profesor, asignatura);
}

@Override
public String toString() {
    return "AsignaturaProfesor{" +
        "profAsigpk=" + profasigpk +
        '}';
} 

thanks if someone can help me.

Kara
  • 145
  • 1
  • 8

2 Answers2

0

It is because while specifying @ManyToOne relationship you are not mentioning the column names which act as foreign key, therefore, hibernate is assuming the foreign key name as per its convention, thus, you are facing this issue. Try this:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(referencedColumnName = "id",name = "id_profesor", insertable=false, updatable=false)
private Profesor profesor;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(referencedColumnName = "id",name = "id_asignatura", insertable=false, updatable=false)
private Asignatura asignatura;
Kara
  • 145
  • 1
  • 8
codeLover
  • 2,571
  • 1
  • 11
  • 27
  • Thanks for your help @codeLover. I tried your suggestion code and that almost run, I only have to chance the fields in referenceColumnane an name like this: @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(referencedColumnName = "id",name = "id_profesor", insertable=false, updatable=false) private Profesor profesor; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(referencedColumnName = "id",name = "id_asignatura", insertable=false, updatable=false) private Asignatura asignatura; – Kara Oct 21 '18 at 00:26
0

Now the code is runing with the @codeLover answer modified like I comment in his answer but if I set fetch=FetchType.EAGER on Profesor.java I get StackOverflowError and if I set fetch=FetchType.LAZY then I do
Page<Profesor> page = profesorRepository.findAll(pageable); I get all without asignaturas list that each profesor have. So, I don't know how I can to get all profesors with all their fields include asignaturas list from each one

Profesor.java

@OneToMany(
mappedBy = "profesor",
cascade = CascadeType.ALL,
fetch=FetchType.EAGER,
orphanRemoval = true
)
private List<AsignaturaProfesor> asignaturas = new ArrayList<>();
Kara
  • 145
  • 1
  • 8
  • I could resolved it with this [link](https://stackoverflow.com/questions/3325387/infinite-recursion-with-jackson-json-and-hibernate-jpa-issue) – Kara Oct 21 '18 at 17:16