Reputation: 734
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
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