Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate @ManyToOne of an entity with @IdClass

I just added a new entity to my project and now it doesn't start. I think it is related to having a @ManyToOne being part of a composite key but I'm not sure. I reduced my problem to the following entities:

A.class:

@Table(name = "A")
@Entity
@IdClass(KeyA.class)
public class A {
    
   @Id
   private String aId;
    
   @Id
   @ManyToOne
   private B b;
    
   public String getaId() {
      return aId;
   }
    
   public void setaId(String aId) {
      this.aId = aId;
   }
    
   public B getB() {
      return b;
   }
    
   public void setB(B b) {
      this.b = b;
   }
}

B.class:

@Table(name = "B")
@Entity
@IdClass(KeyB.class)
public class B {
    
   @Id
   String bId;
    
   @Id
   String bId2;
    
   public String getbId() {
      return bId;
   }
    
   public void setbId(String bId) {
      this.bId = bId;
   }
    
   public String getbId2() {
      return bId2;
   }
    
   public void setbId2(String bId2) {
      this.bId2 = bId2;
   }
}

KeyA.class:

public class KeyA implements Serializable {
    
   private String aId;
   private String b;
}

KeyB.class

public class KeyB implements Serializable{
    
   public String bId;
   public String bId2;
}

Exception thrown:

        Error creating bean with name 'entityManagerFactory' defined in class path resource
        [...]
        Caused by: org.hibernate.HibernateException: Unable to instantiate default tuplizer [org.hibernate.tuple.component.PojoComponentTuplizer]
    [...]
    Caused by: java.lang.reflect.InvocationTargetException: null
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_201]
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_201]
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_201]
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_201]
        at org.hibernate.tuple.component.ComponentTuplizerFactory.constructTuplizer(ComponentTuplizerFactory.java:104) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
        ... 43 common frames omitted
    Caused by: org.hibernate.PropertyNotFoundException: Could not locate field name [bId] on class [java.lang.String]
        at org.hibernate.internal.util.ReflectHelper.findField(ReflectHelper.java:371) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
        at org.hibernate.property.access.internal.PropertyAccessFieldImpl.<init>(PropertyAccessFieldImpl.java:34) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
        at org.hibernate.property.access.internal.PropertyAccessStrategyFieldImpl.buildPropertyAccess(PropertyAccessStrategyFieldImpl.java:26) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
        at org.hibernate.mapping.Property.getGetter(Property.java:311) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
        at org.hibernate.tuple.component.PojoComponentTuplizer.buildGetter(PojoComponentTuplizer.java:141) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]

I tried everything, including importing latest javassist. I'm running Spring Boot 2.2.5.RELEASE on Java 1.8 (it also happens in 11)

like image 660
Carlos López Marí Avatar asked Sep 03 '25 08:09

Carlos López Marí


1 Answers

Your composite key of A

public class KeyA implements Serializable {

    private String aId;
    private String b;
}

is structured as if B would have only a single string ID (here referred to as b) while in reality it has a composite key itself

public class KeyB implements Serializable{

    public String bId;
    public String bId2;
}

so you have to change KeyA to represent that relationship correctly:

public class KeyA implements Serializable {

    private String aId;
    private KeyB keyB;
}
like image 138
Smutje Avatar answered Sep 05 '25 00:09

Smutje