Gal Sosin
Gal Sosin

Reputation: 734

Many to Many org.hibernate.MappingException

I know this question was asked multiple times but I'm loosing my mind, I'm trying to create a Many-To-Many relationship and I'm getting the following exception:

    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mySqlSessionFactory' defined in class path resource [database/hibernate.xml]: Invocation of init method fai
led; nested exception is org.hibernate.MappingException: Could not determine type for: java.util.Set, at table: manager_ova, for columns: [org.hibernate.mapping.Column(availSenss)]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1794)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:330)
        ... 108 more
Caused by: org.hibernate.MappingException: Could not determine type for: java.util.Set, at table: manager_ova, for columns: [org.hibernate.mapping.Column(availSenss)]
        at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:499)
        at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:466)
        at org.hibernate.mapping.Property.isValid(Property.java:227)
        at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:624)
        at org.hibernate.mapping.RootClass.validate(RootClass.java:267)
        at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:354)
        at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:465)
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:708)
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:724)
        at org.springframework.orm.hibernate5.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:616)
        at org.springframework.orm.hibernate5.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:600)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1853)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1790)
        ... 115 more

Entites:

@Entity
@Table(name = "sens")
@Getter
@Setter
@Recoverable(backupOption = BackupOption.BASIC, fileDependecies = {})
public class Sens implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 5622870770478762574L;

    @Id
    @Column(unique = true, nullable = false)
    private Long id;
    
    @Column(unique = false, nullable = false)
    private String name;
    
    @ManyToMany(mappedBy = "availSenss")
    private Set<ManagerOva> ovas;
    
    public Sens() {}

    @Override
    public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((id == null) ? 0 : id.hashCode());
    result = prime * result + ((name == null) ? 0 : name.hashCode());
    result = prime * result + ((ovas == null) ? 0 : ovas.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;
    Sens other = (Sens) obj;
    if (id == null) {
        if (other.id != null)
        return false;
    } else if (!id.equals(other.id))
        return false;
    if (name == null) {
        if (other.name != null)
        return false;
    } else if (!name.equals(other.name))
        return false;
    if (ovas == null) {
        if (other.ovas != null)
        return false;
    } else if (!ovas.equals(other.ovas))
        return false;
    return true;
    }
    
    
}

@Entity
@Table(name = "manager_ova")
@Getter
@Setter
@Recoverable(backupOption = BackupOption.BASIC, fileDependecies = {})
public class ManagerOva implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 2994716515279921578L;

    @Id
    @Column(unique = true, nullable = false)
    private Long id;
    
    @Column(unique = false, nullable = false)
    private String name;
    
    @JoinTable(name = "manager_ova_sens", joinColumns = @JoinColumn(name = "ova_id"), inverseJoinColumns = @JoinColumn(name = "sens_id"))
    private Set<Sens> availSenss;
    
    public ManagerOva() {}

    @Override
    public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((availSenss == null) ? 0 : availSenss.hashCode());
    result = prime * result + ((id == null) ? 0 : id.hashCode());
    result = prime * result + ((name == null) ? 0 : name.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;
    ManagerOva other = (ManagerOva) obj;
    if (availSenss == null) {
        if (other.availSenss != null)
        return false;
    } else if (!availSenss.equals(other.availSenss))
        return false;
    if (id == null) {
        if (other.id != null)
        return false;
    } else if (!id.equals(other.id))
        return false;
    if (name == null) {
        if (other.name != null)
        return false;
    } else if (!name.equals(other.name))
        return false;
    return true;
    }
    
    

}

I'm not sure what I'm doing wrong, spent hours trying to figure out the issue. The help table was created manually with the ova_id, sensor_id as both PK & FK in the table named vm_ova_sensors

Thanks

Upvotes: 1

Views: 80

Answers (1)

SternK
SternK

Reputation: 13111

Every bidirectional association must have one owning side only (the child side), the other one being referred to as the inverse (or the mappedBy) side. As @ManyToMany association is symmetric, the owning side can be either one.

The @JoinTable annotation should be used on the owning side. So, you should correct your mapping in the following way:

@Entity
public class ManagerOVARecord extends OVARecord {

   // ...

   @ManyToMany
   @JoinTable(name = "vm_ova_sensors", 
             joinColumns = @JoinColumn(name = "ova_id"), 
             inverseJoinColumns = @JoinColumn(name = "sensor_id")
   )
   private Set<Sensor> availableOnSensors = new HashSet<>();

   // ...
}

@Entity
@Table(name = "ts_sensors")
public class Sensor implements Identifiable, Serializable {

   // ...
    
   @ManyToMany(mappedBy = "availableOnSensors")
   private Set<ManagerOVARecord> availableOvas = new HashSet<>(); 

   // ...
}

See also this section of the hibernate documentation.

Upvotes: 1

Related Questions