Composite key problems in JPA

Asked

Viewed 785 times

2

Hi, I’m a little young with JPA and I’m having problems with a composite PK.

Follows the class Aluno:

@Entity
@Table(name = "Aluno")
public class Aluno {

    @Id
    private String ra;

    @Column(length = 50, nullable = false)
    private String nome;

    @Column(length = 1, nullable = false)
    private char sexo;

    @Temporal(TemporalType.DATE)
    private Date anoIngresso;

    @Column(nullable = false)
    private int semestreCur;

    @ManyToOne(optional = false)
    private Curso curso;

    @ManyToMany
    @JoinTable(name = "aluno_disciplina", joinColumns = {@JoinColumn(name = "ra_aluno", foreignKey = @ForeignKey(name = "aluno_disc_fk"))}, 
                                      inverseJoinColumns = {@JoinColumn(name = "cod_disciplina", foreignKey = @ForeignKey(name = "disc_aluno_fk"))} 
    )
    private List<Disciplina> disciplinas;

    @OneToMany(mappedBy = "aluno")
    @JsonIgnore
    private List<Publicacao> publicacoes;

    @OneToOne(mappedBy = "aluno")
    @JsonIgnore
    private Usuario usuario;

    //getters e setters

This is my class Curso:

@Entity
@IdClass(CursoId.class)
@Table(name = "curso")
    public class Curso {

    @Id
    @Column(length = 20)
    private String sigla;

    @Column(length = 50, nullable = false)
    private String nome;

    @Id
    @Column(length = 1)
    private char periodo;

    @Column(nullable = false)
    private int numSemestres;

    @OneToMany(mappedBy = "curso")
    @JsonIgnore
    private List<Disciplina> disciplinas;

    @OneToMany
    @JoinTable(
    joinColumns = {@JoinColumn(name = "periodo_curso", referencedColumnName = "periodo", foreignKey = @ForeignKey(name = "curso_aluno_fk1")),
                   @JoinColumn(name = "sigla_curso", referencedColumnName = "sigla", foreignKey = @ForeignKey(name = "curso_aluno_fk2"))},
    inverseJoinColumns = @JoinColumn(name = "aluno_ra", foreignKey = @ForeignKey(name = "aluno_curso_fk"))
    )
    private List<Aluno> alunos;

    @ManyToMany(mappedBy = "cursos")
    @JsonIgnore
    private List<Colaborador> professores;

    //getters e setters

And here the class CursoId that I use to make the PK composed of class Curso:

public class CursoId implements Serializable {

    private static final long serialVersionUID = 3354490326116698299L;

    private String sigla;
    private char periodo;

    public CursoId () {

    }

    public CursoId (String sigla, char periodo) {
        this.sigla = sigla;
        this.periodo = periodo;
    }

    public String getSigla() {
        return sigla;
    }

    public char getPeriodo() {
        return periodo;
    }

    public void setSigla(String sigla) {
        this.sigla = sigla;
    }

    public void setPeriodo(char periodo) {
        this.periodo = periodo;
    }

    @Override
    public int hashCode() {
        final int prime = 31;    
        int result = 1;
        result = prime * result + periodo;
        result = prime * result + ((sigla == null) ? 0 : sigla.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        CursoId other = (CursoId) obj;
        if (periodo != other.periodo)
            return false;
        if (sigla == null) {
            if (other.sigla != null)
                return false;
        } else if (!sigla.equals(other.sigla))
            return false;
        return true;
    }
}

It turns out that when JPA will create the schema in the database, it throws this exception:

org.hibernate.tool.schema.spi.CommandAcceptanceException: Unable to execute command [alter table curso_Aluno add constraint aluno_curso_fk foreign key (aluno_ra) references Aluno]
    at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:63) ~[hibernate-core-5.2.1.Final.jar:5.2.1.Final]
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.applySqlString(SchemaMigratorImpl.java:573) [hibernate-core-5.2.1.Final.jar:5.2.1.Final]
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.applySqlStrings(SchemaMigratorImpl.java:557) [hibernate-core-5.2.1.Final.jar:5.2.1.Final]
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.applyForeignKeys(SchemaMigratorImpl.java:516) [hibernate-core-5.2.1.Final.jar:5.2.1.Final]
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.performMigration(SchemaMigratorImpl.java:315) [hibernate-core-5.2.1.Final.jar:5.2.1.Final]
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.doMigration(SchemaMigratorImpl.java:137) [hibernate-core-5.2.1.Final.jar:5.2.1.Final]
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.doMigration(SchemaMigratorImpl.java:110) [hibernate-core-5.2.1.Final.jar:5.2.1.Final]
    at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:176) [hibernate-core-5.2.1.Final.jar:5.2.1.Final]
    at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:65) [hibernate-core-5.2.1.Final.jar:5.2.1.Final]
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:308) [hibernate-core-5.2.1.Final.jar:5.2.1.Final]
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:483) [hibernate-core-5.2.1.Final.jar:5.2.1.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:888) [hibernate-core-5.2.1.Final.jar:5.2.1.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) [spring-orm-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:338) [spring-orm-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:373) [spring-orm-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:362) [spring-orm-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637) [spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) [spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545) [spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) [spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) [spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) [spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) [spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) [spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1076) [spring-context-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:851) [spring-context-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541) [spring-context-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:760) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
    at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:360) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:306) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1185) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1174) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
    at edu.fatec.mural.config.MuralApp.main(MuralApp.java:35) [classes/:na]
Caused by: java.sql.SQLIntegrityConstraintViolationException: ORA-02298: não é possível validar (RAFAEL.ALUNO_CURSO_FK) - chaves mães não localizadas

    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:447) ~[ojdbc6-1.0.jar:11.2.0.4.0]
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396) ~[ojdbc6-1.0.jar:11.2.0.4.0]
    at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:951) ~[ojdbc6-1.0.jar:11.2.0.4.0]
    at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:513) ~[ojdbc6-1.0.jar:11.2.0.4.0]
    at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:227) ~[ojdbc6-1.0.jar:11.2.0.4.0]
    at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531) ~[ojdbc6-1.0.jar:11.2.0.4.0]
    at oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:195) ~[ojdbc6-1.0.jar:11.2.0.4.0]
    at oracle.jdbc.driver.T4CStatement.executeForRows(T4CStatement.java:1036) ~[ojdbc6-1.0.jar:11.2.0.4.0]
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1336) ~[ojdbc6-1.0.jar:11.2.0.4.0]
    at oracle.jdbc.driver.OracleStatement.executeInternal(OracleStatement.java:1916) ~[ojdbc6-1.0.jar:11.2.0.4.0]
    at oracle.jdbc.driver.OracleStatement.execute(OracleStatement.java:1878) ~[ojdbc6-1.0.jar:11.2.0.4.0]
    at oracle.jdbc.driver.OracleStatementWrapper.execute(OracleStatementWrapper.java:318) ~[ojdbc6-1.0.jar:11.2.0.4.0]
    at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:51) ~[hibernate-core-5.2.1.Final.jar:5.2.1.Final]
    ... 33 common frames omitted

Hibernate: alter table curso_Aluno add constraint curso_aluno_fk1 foreign key (periodo_curso, sigla_curso) references curso
2016-08-19 01:02:06.691  WARN 12080 --- [           main] o.h.t.s.i.ExceptionHandlerLoggedImpl     : GenerationTarget encountered exception accepting command : Unable to execute command [alter table curso_Aluno add constraint curso_aluno_fk1 foreign key (periodo_curso, sigla_curso) references curso]

org.hibernate.tool.schema.spi.CommandAcceptanceException: Unable to execute command [alter table curso_Aluno add constraint curso_aluno_fk1 foreign key (periodo_curso, sigla_curso) references curso]
    at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:63) ~[hibernate-core-5.2.1.Final.jar:5.2.1.Final]
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.applySqlString(SchemaMigratorImpl.java:573) [hibernate-core-5.2.1.Final.jar:5.2.1.Final]
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.applySqlStrings(SchemaMigratorImpl.java:557) [hibernate-core-5.2.1.Final.jar:5.2.1.Final]
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.applyForeignKeys(SchemaMigratorImpl.java:516) [hibernate-core-5.2.1.Final.jar:5.2.1.Final]
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.performMigration(SchemaMigratorImpl.java:315) [hibernate-core-5.2.1.Final.jar:5.2.1.Final]
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.doMigration(SchemaMigratorImpl.java:137) [hibernate-core-5.2.1.Final.jar:5.2.1.Final]
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.doMigration(SchemaMigratorImpl.java:110) [hibernate-core-5.2.1.Final.jar:5.2.1.Final]
    at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:176) [hibernate-core-5.2.1.Final.jar:5.2.1.Final]
    at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:65) [hibernate-core-5.2.1.Final.jar:5.2.1.Final]
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:308) [hibernate-core-5.2.1.Final.jar:5.2.1.Final]
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:483) [hibernate-core-5.2.1.Final.jar:5.2.1.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:888) [hibernate-core-5.2.1.Final.jar:5.2.1.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) [spring-orm-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:338) [spring-orm-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:373) [spring-orm-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:362) [spring-orm-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637) [spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) [spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545) [spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) [spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) [spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) [spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) [spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) [spring-beans-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1076) [spring-context-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:851) [spring-context-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541) [spring-context-4.3.1.RELEASE.jar:4.3.1.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:760) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
    at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:360) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:306) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1185) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1174) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
    at edu.fatec.mural.config.MuralApp.main(MuralApp.java:35) [classes/:na]
Caused by: java.sql.SQLIntegrityConstraintViolationException: ORA-02298: não é possível validar (RAFAEL.CURSO_ALUNO_FK1) - chaves mães não localizadas

    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:447) ~[ojdbc6-1.0.jar:11.2.0.4.0]
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396) ~[ojdbc6-1.0.jar:11.2.0.4.0]
    at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:951) ~[ojdbc6-1.0.jar:11.2.0.4.0]
    at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:513) ~[ojdbc6-1.0.jar:11.2.0.4.0]
    at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:227) ~[ojdbc6-1.0.jar:11.2.0.4.0]
    at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531) ~[ojdbc6-1.0.jar:11.2.0.4.0]
    at oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:195) ~[ojdbc6-1.0.jar:11.2.0.4.0]
    at oracle.jdbc.driver.T4CStatement.executeForRows(T4CStatement.java:1036) ~[ojdbc6-1.0.jar:11.2.0.4.0]
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1336) ~[ojdbc6-1.0.jar:11.2.0.4.0]
    at oracle.jdbc.driver.OracleStatement.executeInternal(OracleStatement.java:1916) ~[ojdbc6-1.0.jar:11.2.0.4.0]
    at oracle.jdbc.driver.OracleStatement.execute(OracleStatement.java:1878) ~[ojdbc6-1.0.jar:11.2.0.4.0]
    at oracle.jdbc.driver.OracleStatementWrapper.execute(OracleStatementWrapper.java:318) ~[ojdbc6-1.0.jar:11.2.0.4.0]
    at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:51) ~[hibernate-core-5.2.1.Final.jar:5.2.1.Final]
    ... 33 common frames omitted

Who can help me solve this problem I thank!

  • Have you tried using @EmbeddedId instead of @IdClass?

  • I used the @EmbeddedId in the Course class and the @Embeddable in the Cursoid class, that solved my problem, thank you!

1 answer

1


In class Curso, the CursoId replaced the fields sigla and periodo, and the @IdClass was removed:

@EmbeddedId
private CursoId cursoId;
//getter e setter pro CursoId também adicionados

In class CursoId has been added to Annotation @Embeddable:

@Embeddable
public class CursoId implements Serializable

Browser other questions tagged

You are not signed in. Login or sign up in order to post.