Hibernate Books

All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: ManyToOne relation with PK embededId
PostPosted: Wed Mar 22, 2017 6:37 am 
Newbie

Joined: Wed Mar 22, 2017 6:29 am
Posts: 2
Hi.

I have some issues mapping a ManyToOne relation with an entitty having composite EmbeddedId.
I have the following situation:

TABLE 1:
########

Code:
@Entity
@Table(name = "punti_campionamento_t009")
public class PuntoCampionamento {
   private long puntoCampionamentoId;
   
   private Set<PuntoCampionamentoIndagine> puntoCampionamentoIndagine = new HashSet<>();
   ......
   ......
   
   @OneToMany(fetch=FetchType.LAZY, mappedBy="pk.puntoCampionamento")
   public Set<PuntoCampionamentoIndagine> getPuntoCampionamentoIndagine() {
      return puntoCampionamentoIndagine;
   }
   public void setPuntoCampionamentoIndagine(Set<PuntoCampionamentoIndagine> puntoCampionamentoIndagine) {
      this.puntoCampionamentoIndagine = puntoCampionamentoIndagine;
   }
}


TABBLE 2:
##########

Code:
@Entity
@Table(name = "tipo_indagine_t005")
public class TipoIndagine implements {
   private long tipoIndagineId;
   ........
   ........
}



TABLE 3: PK of the first two entities
########

Code:
@Embeddable
public class PuntoCampionamentoIndagineId implements Serializable {
   
   private PuntoCampionamento puntoCampionamento;
   private TipoIndagine tipoIndagine;
   
   @ManyToOne(fetch=FetchType.LAZY)
   public PuntoCampionamento getPuntoCampionamento() {
      return puntoCampionamento;
   }
   public void setPuntoCampionamento(PuntoCampionamento puntoCampionamento) {
      this.puntoCampionamento = puntoCampionamento;
   }
   
   @ManyToOne(fetch=FetchType.LAZY)
   public TipoIndagine getTipoIndagine() {
      return tipoIndagine;
   }
   public void setTipoIndagine(TipoIndagine tipoIndagine) {
      this.tipoIndagine = tipoIndagine;
   }   
}


TABLE 4:
########

Code:
@Entity
@Table(name = "punti_campionamento_indagine_t013")
@AssociationOverrides({
   @AssociationOverride(name="pk.puntoCampionamento", joinColumns = @JoinColumn(name="p_punto_campionamento", nullable = false)),
   @AssociationOverride(name="pk.tipoIndagine", joinColumns = @JoinColumn(name="p_tipo_indagine", nullable = false)),
})
public class PuntoCampionamentoIndagine {
   private long puntoCampionamentoIndagineSerial;
   private Set<Campione> campioni;
   private PuntoCampionamentoIndagineId pk = new PuntoCampionamentoIndagineId();
   
   @EmbeddedId
   public PuntoCampionamentoIndagineId getPk() {
      return pk;
   }
   
   public void setPk(PuntoCampionamentoIndagineId pk) {
      this.pk = pk;
   }
   
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(name = "p_punto_campionamento_indagine", nullable = false, unique = true)
   public long getPuntoCampionamentoIndagineSerial() {
      return puntoCampionamentoIndagineSerial;
   }
   public void setPuntoCampionamentoIndagineSerial(long puntoCampionamentoIndagineSerial) {
      this.puntoCampionamentoIndagineSerial = puntoCampionamentoIndagineSerial;
   }
   
   ???????????????????????????????????????????????????????
   ???????? ---> THIS IS THE "ONE TO MANY" THAT doesn't work
   ???????????????????????????????????????????????????????
   @OneToMany(fetch=FetchType.LAZY, mappedBy="puntoCampionamentoIndagine")
   public Set<Campione> getCampioni() {
      return campioni;
   }
   public void setCampioni(Set<Campione> campioni) {
      this.campioni = campioni;
   }
}



TABLE 5:
#########

Code:
@Entity
@Table(name = "campioni_t011")
public class Campione {
   private long campioneId;
   
   //--> Property related to TABLE 4
   private PuntoCampionamentoIndagine puntoCampionamentoIndagine;
   
   //?????????????????????????????????????????????????????????????????????????????????????????
   //--> what i have to set here to make relation with table 3 (PuntoCampionamentoIndagine) ???
   //--> The foreign key in datatabse is on the table id (getPuntoCampionamentoIndagineSerial)
   //??????????????????????????????????????????????????????????????????????????????????????????
   
   @ManyToOne(fetch = FetchType.LAZY)
   @JoinColumns({
        @JoinColumn(name="p_punto_campionamento_indagine", referencedColumnName="p_punto_campionamento_indagine")
    })
   public PuntoCampionamentoIndagine getPuntoCampionamentoIndagine() {
      return puntoCampionamentoIndagine;
   }
   public void setPuntoCampionamento(PuntoCampionamentoIndagine puntoCampionamentoIndagine) {
      this.puntoCampionamentoIndagine = puntoCampionamentoIndagine;
   }

}


The problem is on entity "Campione". I can not create the proper relation with the entity "PuntoCampionamentoIndagine".


Last edited by mirko.lv on Wed Mar 22, 2017 7:29 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: ManyToOne relation with PK embededId
PostPosted: Wed Mar 22, 2017 7:05 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1527
In entity PuntoCampionamentoIndagine, why do you use this generated column:

Code:
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(name = "p_punto_campionamento_indagine", nullable = false, unique = true)
   public long getPuntoCampionamentoIndagineSerial() {
      return puntoCampionamentoIndagineSerial;
   }


since the entity identifier is PuntoCampionamentoIndagineId.

Either you use a generated id, or a composite key, but not both.

Also, what do you mean it does not work? Do you get some exception? I see you didn't set cascade, so is it that you save the PuntoCampionamentoIndagine and the Set of Campione is not saved?

_________________
If you liked my answer, you are going to love my High-Performance Java Persistence book and my blog as well.


Top
 Profile  
 
 Post subject: Re: ManyToOne relation with PK embededId
PostPosted: Wed Mar 22, 2017 7:26 am 
Newbie

Joined: Wed Mar 22, 2017 6:29 am
Posts: 2
Thank you very much for quick reply.

As you said the problem is that i have the "p_punto_campionamento_indagine" into the database as serial autogenerated and set it as "generated Id", and the composite id as PK.

I can remove the generated Id but i have to set the the foreign key between "Campione" and "PuntoCampionamentoIndagine" on "p_punto_campionamento_indagine".

With this declaration in "Campione" on FK field "PuntoCampionamentoIndagine":

Code:
@ManyToOne(fetch = FetchType.LAZY)
   @JoinTable(name="punti_campionamento_indagine_t013",
    joinColumns={
        @JoinColumn(name="p_punto_campionamento_indagine")
    })
   public PuntoCampionamentoIndagine getPuntoCampionamentoIndagine() {
      return puntoCampionamentoIndagine;
   }
   public void setPuntoCampionamento(PuntoCampionamentoIndagine puntoCampionamentoIndagine) {
      this.puntoCampionamentoIndagine = puntoCampionamentoIndagine;
   }



the exception i get is the following:

Quote:
2017-03-22 12:04:34 INFO BasicTypeRegistry:139 - HHH000270: Type registration [java.util.UUID] overrides previous : org.hibernate.type.UUIDBinaryType@1134e771
2017-03-22 12:04:35 FATAL SessionFactoryManager:78 - Error building Session Factory
org.hibernate.MappingException: Foreign key (FKn3bbt93c3rbmchvnkl501m0vr:punti_campionamento_indagine_t013 [puntoCampionamentoIndagine_p_punto_campionamento,puntoCampionamentoIndagine_p_tipo_indagine])) must have same number of columns as the referenced primary key (punti_campionamento_indagine_t013 [p_punto_campionamento_indagine])
at org.hibernate.mapping.ForeignKey.alignColumns(ForeignKey.java:148)
at org.hibernate.mapping.ForeignKey.alignColumns(ForeignKey.java:130)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.secondPassCompileForeignKeys(InFlightMetadataCollectorImpl.java:1854)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.secondPassCompileForeignKeys(InFlightMetadataCollectorImpl.java:1774)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1593)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:278)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:83)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:418)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:87)
at org.hibernate.boot.MetadataSources.buildMetadata(MetadataSources.java:179)
at it.gesp.commons.dao.SessionFactoryManager.initSessionFactory(SessionFactoryManager.java:63)
at it.gesp.commons.listeners.AppStartListener.contextInitialized(AppStartListener.java:29)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4738)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5181)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Mar 22, 2017 12:04:35 PM org.apache.catalina.core.StandardContext listenerStart
SEVERE: Exception sending context initialized event to listener instance of class it.gesp.commons.listeners.AppStartListener
java.lang.Error
at it.gesp.commons.dao.SessionFactoryManager.initSessionFactory(SessionFactoryManager.java:79)
at it.gesp.commons.listeners.AppStartListener.contextInitialized(AppStartListener.java:29)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4738)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5181)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

Mar 22, 2017 12:04:35 PM org.apache.catalina.core.StandardContext startInternal
SEVERE: One or more listeners failed to start. Full details will be found in the appropriate container log file
Mar 22, 2017 12:04:35 PM org.apache.catalina.core.StandardContext startInternal
SEVERE: Context [/wgilva] startup failed due to previous errors
2017-03-22 12:04:35 INFO AppStartListener:48 - Context Destroyed: Shutting down Hibernate Session Factory....
2017-03-22 12:04:35 INFO SessionFactoryManager:33 - Shutting down session factory.
2017-03-22 12:04:35 INFO SessionFactoryManager:37 - Session factory successfully shut down.
2017-03-22 12:04:35 INFO AppStartListener:50 - Context Destroyed: Session Factory shut down.
2017-03-22 12:04:35 INFO AppStartListener:56 - Initializing Executor Services
2017-03-22 12:04:35 INFO ExecutorFactoryManager:23 - Shutting down executor service.
2017-03-22 12:04:35 INFO ExecutorFactoryManager:27 - Executor service successfully shut down.
2017-03-22 12:04:35 INFO AppStartListener:58 - Executor Services initialized.
Mar 22, 2017 12:04:35 PM org.apache.catalina.loader.WebappClassLoaderBase clearReferencesJdbc
WARNING: The web application [wgilva] registered the JDBC driver [org.postgresql.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
Mar 22, 2017 12:04:35 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-nio-8080"]
Mar 22, 2017 12:04:35 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-nio-8009"]
Mar 22, 2017 12:04:35 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 4496 ms


Top
 Profile  
 
 Post subject: Re: ManyToOne relation with PK embededId
PostPosted: Wed Mar 22, 2017 8:08 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1527
A @manyToOne association to PuntoCampionamentoIndagine requires you to provide the composite key, not just one column. This is the same with any database relationship.

_________________
If you liked my answer, you are going to love my High-Performance Java Persistence book and my blog as well.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
cron
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.