Use foreign key as primary key - Hibernate

Asked

Viewed 939 times

1

I am implementing Hibernate in my project and arrived at a stage where I am having problems to map my entities.

I have an entity called Book and would like to create a Stock entity to store the number of books I own, however, I would like to use the primary book key in my stock entity to ensure that each book will have only one record in the stock table.

My Book Class:

@Entity
public class Livro {

    @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="idLivro")
    private int idLivro;

    @Column(length=70)
    private String titulo;
    @Column(columnDefinition="TEXT")
    private String descricao;
    private int edicao;
    @Temporal(TemporalType.DATE)
    private Date dataLancamento;
    private int numeroPaginas;
    private long ISBN;
    @ManyToMany
    private List<Categoria> categorias;
    @ManyToOne
    private Editora editora;

    //getters e setters

And my stock class:

@Entity
public class Estoque {
    @OneToOne(cascade=CascadeType.ALL)  
    @PrimaryKeyJoinColumn 
    private Livro livro;
    private int quantidade;

    // Getters e Setters

Meanwhile I get the message on the console:

Exception in thread "main" org.hibernate.AnnotationException: No identifier specified for entity: br.com.biblioteca.model.Estoque
    at org.hibernate.cfg.InheritanceState.determineDefaultAccessType(InheritanceState.java:266)
    at org.hibernate.cfg.InheritanceState.getElementsToProcess(InheritanceState.java:211)
    at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:719)
    at org.hibernate.boot.model.source.internal.annotations.AnnotationMetadataSourceProcessorImpl.processEntityHierarchies(AnnotationMetadataSourceProcessorImpl.java:249)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess$1.processEntityHierarchies(MetadataBuildingProcess.java:222)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:265)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:858)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:885)
    at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:58)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39)
    at br.com.biblioteca.model.Main.main(Main.java:11)

What if I add the Annotation @Id :

@Entity
public class Estoque {
    @Id
    @OneToOne(cascade=CascadeType.ALL)  
    @PrimaryKeyJoinColumn 
    private Livro livro;

I get the following message on the console:

Exception in thread "main" javax.persistence.PersistenceException: Unable to build entity manager factory
    at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:66)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39)
    at br.com.biblioteca.model.Main.main(Main.java:11)
Caused by: java.lang.NullPointerException
    at org.hibernate.mapping.PersistentClass.createPrimaryKey(PersistentClass.java:363)
    at org.hibernate.cfg.CreateKeySecondPass.doSecondPass(CreateKeySecondPass.java:31)
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1621)
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1585)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:278)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:858)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:885)
    at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:58)
    ... 3 more

2 answers

1

  • I’ve tried using @id and still have problems:

1


Try to use the annotation @Mapsid thus:

@Entity
public class Estoque {
    @Id
    private int id;

    @MapsId("id")
    @OneToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="id", referencedColumnName="idLivro")  
    private Livro livro;
}
  • But then Hibernate creates two id fields, is that normal? My intention was to have only 1

  • @Cleitonribeiro Then add the annotation @JoinColumn and delete the table Estoque for Hibernate to recreate it, I edited my reply with the amendment.

  • very grateful! helped me a lot.

Browser other questions tagged

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