Use foreign key as primary key - Hibernate

1

I'm implementing hibernate in my project and I've reached a stage when I'm having trouble mapping my entities.

I have an entity called Book and would like to create an Inventory entity to store the number of books I have, however, I would like to use the primary key of book in my stock entity to ensure that each book will have only a single record in the inventory 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

However, I get the message in 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)

And if I add the annotation @Id:

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

I get the following message in 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
    
asked by anonymous 05.03.2017 / 20:40

2 answers

1

Try using the annotation @MapsId like this:

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

    @MapsId("id")
    @OneToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="id", referencedColumnName="idLivro")  
    private Livro livro;
}
    
05.03.2017 / 21:44
1

To use the hibernate annotations, you must define an attribute with the @Id annotation. This is a premise.

link

    
05.03.2017 / 20:57