ManyToMany单向、双向:@JoinTable的使用

 更新时间:2021年12月06日 11:48:52   作者:FixedStarHaHa  
这篇文章主要介绍了ManyToMany单向、双向:@JoinTable的使用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

ManyToMany单向、双向:@JoinTable使用

一、manytomany单向

单向是指类层面,在下面例子中老师类可以知道要教哪些学生,学生不知被哪些老师教

**需要用到连接表**@JoinTable(name="t_s",
joinColumns={@JoinColumn(name="teacher_id")},inverseJoinColumns={@JoinColumn(name="student_id")}
)

也可以不用连接表,但是若不用连接表,表名、列名规则:

  • 在student表中没有写外键则会用对方的表名_主键名
  • 在teacher表中有外键,则会s_id(也是student的主键名)
  • 表名是student_teacher

student类

@Entity
public class student {
    private int id;
    private String name;
    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

Teacher类

@Entity 
public class teacher {
    private int id;
    private String name;
    private Set<student> s=new HashSet<student>();
    @Id //必须加在getId上面
    @GeneratedValue
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    @ManyToMany
    @JoinTable(name="t_s",
    joinColumns={@JoinColumn(name="teacher_id")},inverseJoinColumns={@JoinColumn(name="student_id")}
    )//将会以上两个字段为联合主键
    //定义中间表的名称,列名:joinColumns,inverseJoinColumns是预防组合主键的时候。
    public Set<student> getS() {
        return s;
    }
    public void setS(Set<student> s) {
        this.s = s;
    }   
}

二、manytomany双向

也可以用@JoinTable对连接表字段名进行修改

@Entity
public class student {
    private int id;
    private String name;
    private Set<teacher> ts=new HashSet<teacher>();
    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @ManyToMany
    @JoinTable(name="t_s",
    joinColumns={@JoinColumn(name="teacher_id")},inverseJoinColumns={@JoinColumn(name="student_id")}
    )
    public Set<teacher> getTs() {
        return ts;
    }
    public void setTs(Set<teacher> ts) {
        this.ts = ts;
    }
}
@Entity 
public class teacher {
    private int id;
    private String name;
    private Set<student> s=new HashSet<student>();
    @Id //必须加在getId上面
    @GeneratedValue
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @ManyToMany(mappedBy="ts")
    //定义中间表的名称,列名:joinColumns,inverseJoinColumns是预防组合主键的时候。
    public Set<student> getS() {
        return s;
    }
    public void setS(Set<student> s) {
        this.s = s;
    }
}

@ManyToMany(多对多关系)使用小结

DeviceGroup类

package com.sunwave.grouping.domain;
import javax.persistence.*;
import java.io.Serializable;
import java.util.List;
@Entity
@Table(name = "device_group")
public class DeviceGroup implements Serializable{
    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	@Id
    @GeneratedValue(strategy = GenerationType.AUTO)
   /* @Column(name="group_id")*/
    private long groupId;
    @Column(name="group_name")
    private String groupName;
    @Column(name="description")
    private String description;//自动在数据库里生成了group_has_element表,该表包括group_id和element_id两个字段,该表主要是用于存储device_group表和ne_element表的对应关系。
    @ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)//表的关联,生成一个group_has_element中间表。
    @JoinTable(name = "group_has_element",joinColumns = {@JoinColumn(name = "group_id",referencedColumnName = "groupId")}
    ,inverseJoinColumns = {@JoinColumn(name = "element_id",referencedColumnName = "neNeid")})
    private List<NeElement> elementList;
    
    public List<NeElement> getElementList() {
		return elementList;
	}
	public void setElementList(List<NeElement> elementList) {
		this.elementList = elementList;
	}
	public long getGroupId() {
		return groupId;
	}
	public void setGroupId(long groupId) {
		this.groupId = groupId;
	}
	public String getGroupName() {
		return groupName;
	}
	public void setGroupName(String groupName) {
		this.groupName = groupName;
	}
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	@Override
	public String toString() {
		return "DeviceGroup [groupId=" + groupId + ", groupName=" + groupName + ", description=" + description
				+ ", elementList=" + elementList + "]";
	}
	
    
    
}

NeElement 类

package com.sunwave.grouping.domain;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
 * @author lfw
 * @date   2020年8月3日
 * @time   下午6:44:54
 * 
 */
@Entity
@Table(name = "ne_element")
public class NeElement implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long neNeid; //设备唯一标识
	private String coonReqUrl; //设备连接URL
	private String serialNumber; //设备序列号
	private String deviceIp;  //设备IP
	private Long modelId;//modelName对应的id
	private String description;//描述
	private String manufacturer;//制造商
	private String softwareVersion;//软件版本
	private Date creationTime;//创建时间
	private Date lastBootstrapTime;
	private Date lastConnTime;//最后连接时间
	private Date updateTime;//更新时间
	private String oui;//oui
	private String product;
	private Boolean authRequirement;//是否需要认证
	private String dialectIP;
	private String updateUser;//更新用户
	private String macAddress;//mac地址
	private Integer onlineStatus;//在线状态
	private Integer sessionStatus;//会话状态
   @ManyToMany(mappedBy = "elementList")
	private List<DeviceGroup> deviceGroupList;
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	public String getManufacturer() {
		return manufacturer;
	}
	public void setManufacturer(String manufacturer) {
		this.manufacturer = manufacturer;
	}
	public String getSoftwareVersion() {
		return softwareVersion;
	}
	public void setSoftwareVersion(String softwareVersion) {
		this.softwareVersion = softwareVersion;
	}
	public Date getLastConnTime() {
		return lastConnTime;
	}
	public void setLastConnTime(Date lastConnTime) {
		this.lastConnTime = lastConnTime;
	}
	public Long getModelId() {
		return modelId;
	}
	public void setModelId(Long modelId) {
		this.modelId = modelId;
	}
	public Long getNeNeid() {
		return neNeid;
	}
	public void setNeNeid(Long neNeid) {
		this.neNeid = neNeid;
	}
	public String getCoonReqUrl() {
		return coonReqUrl;
	}
	public void setCoonReqUrl(String coonReqUrl) {
		this.coonReqUrl = coonReqUrl;
	}
	public String getDeviceIp() {
		return deviceIp;
	}
	public void setDeviceIp(String deviceIp) {
		this.deviceIp = deviceIp;
	}
	public String getSerialNumber() {
		return serialNumber;
	}
	public void setSerialNumber(String serialNumber) {
		this.serialNumber = serialNumber;
	}
	public Date getCreationTime() {
		return creationTime;
	}
	public void setCreationTime(Date creationTime) {
		this.creationTime = creationTime;
	}
	public Date getLastBootstrapTime() {
		return lastBootstrapTime;
	}
	public void setLastBootstrapTime(Date lastBootstrapTime) {
		this.lastBootstrapTime = lastBootstrapTime;
	}
	public Date getUpdateTime() {
		return updateTime;
	}
	public void setUpdateTime(Date updateTime) {
		this.updateTime = updateTime;
	}
	public String getOui() {
		return oui;
	}
	public void setOui(String oui) {
		this.oui = oui;
	}
	public String getProduct() {
		return product;
	}
	public void setProduct(String product) {
		this.product = product;
	}
	public Boolean getAuthRequirement() {
		return authRequirement;
	}
	public void setAuthRequirement(Boolean authRequirement) {
		this.authRequirement = authRequirement;
	}
	public String getDialectIP() {
		return dialectIP;
	}
	public void setDialectIP(String dialectIP) {
		this.dialectIP = dialectIP;
	}
	public String getUpdateUser() {
		return updateUser;
	}
	public void setUpdateUser(String updateUser) {
		this.updateUser = updateUser;
	}
	public String getMacAddress() {
		return macAddress;
	}
	public void setMacAddress(String macAddress) {
		this.macAddress = macAddress;
	}
	public Integer getOnlineStatus() {
		return onlineStatus;
	}
	public void setOnlineStatus(Integer onlineStatus) {
		this.onlineStatus = onlineStatus;
	}
	public Integer getSessionStatus() {
		return sessionStatus;
	}
	public void setSessionStatus(Integer sessionStatus) {
		this.sessionStatus = sessionStatus;
	}
}

以上为多对多关系的使用,大家可以参考,本人在使用过程中遇到以下报错信息:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: Unable to map collection com.sunwave.grouping.domain.DeviceGroup.elementList
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1694) ~[spring-beans-5.0.12.RELEASE.jar:5.0.12.RELEASE]
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:573) ~[spring-beans-5.0.12.RELEASE.jar:5.0.12.RELEASE]
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495) ~[spring-beans-5.0.12.RELEASE.jar:5.0.12.RELEASE]
 at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317) ~[spring-beans-5.0.12.RELEASE.jar:5.0.12.RELEASE]
 at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.0.12.RELEASE.jar:5.0.12.RELEASE]
 at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) ~[spring-beans-5.0.12.RELEASE.jar:5.0.12.RELEASE]
 at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.0.12.RELEASE.jar:5.0.12.RELEASE]
 at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1087) ~[spring-context-5.0.12.RELEASE.jar:5.0.12.RELEASE]
 at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:857) ~[spring-context-5.0.12.RELEASE.jar:5.0.12.RELEASE]
 at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:548) ~[spring-context-5.0.12.RELEASE.jar:5.0.12.RELEASE]
 at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142) ~[spring-boot-2.0.8.RELEASE.jar:2.0.8.RELEASE]
 at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) [spring-boot-2.0.8.RELEASE.jar:2.0.8.RELEASE]
 at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:386) [spring-boot-2.0.8.RELEASE.jar:2.0.8.RELEASE]
 at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) [spring-boot-2.0.8.RELEASE.jar:2.0.8.RELEASE]
 at org.springframework.boot.SpringApplication.run(SpringApplication.java:1242) [spring-boot-2.0.8.RELEASE.jar:2.0.8.RELEASE]
 at org.springframework.boot.SpringApplication.run(SpringApplication.java:1230) [spring-boot-2.0.8.RELEASE.jar:2.0.8.RELEASE]
 at com.sunwave.Application.main(Application.java:26) [classes/:na]
 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
 at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
 at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
 at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-2.0.8.RELEASE.jar:2.0.8.RELEASE]
Caused by: org.hibernate.AnnotationException: Unable to map collection com.sunwave.grouping.domain.DeviceGroup.elementList
 at org.hibernate.cfg.annotations.CollectionBinder.bindCollectionSecondPass(CollectionBinder.java:1621) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
 at org.hibernate.cfg.annotations.CollectionBinder.bindManyToManySecondPass(CollectionBinder.java:1352) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
 at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:810) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
 at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:735) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
 at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:54) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
 at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1640) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
 at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1608) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
 at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:278) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
 at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:861) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
 at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:888) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
 at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:57) ~[spring-orm-5.0.12.RELEASE.jar:5.0.12.RELEASE]
 at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.0.12.RELEASE.jar:5.0.12.RELEASE]
 at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:390) ~[spring-orm-5.0.12.RELEASE.jar:5.0.12.RELEASE]
 at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377) ~[spring-orm-5.0.12.RELEASE.jar:5.0.12.RELEASE]
 at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.0.12.RELEASE.jar:5.0.12.RELEASE]
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1753) ~[spring-beans-5.0.12.RELEASE.jar:5.0.12.RELEASE]
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1690) ~[spring-beans-5.0.12.RELEASE.jar:5.0.12.RELEASE]
 ... 21 common frames omitted
Caused by: org.hibernate.cfg.RecoverableException: Unable to find column with logical name: groupId in org.hibernate.mapping.Table(device_group) and its related supertables and secondary tables
 at org.hibernate.cfg.Ejb3JoinColumn.checkReferencedColumnsType(Ejb3JoinColumn.java:837) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
 at org.hibernate.cfg.BinderHelper.createSyntheticPropertyReference(BinderHelper.java:244) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
 at org.hibernate.cfg.annotations.CollectionBinder.bindCollectionSecondPass(CollectionBinder.java:1611) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
 ... 37 common frames omitted
Caused by: org.hibernate.MappingException: Unable to find column with logical name: groupId in org.hibernate.mapping.Table(device_group) and its related supertables and secondary tables
 at org.hibernate.cfg.Ejb3JoinColumn.checkReferencedColumnsType(Ejb3JoinColumn.java:832) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
 ... 39 common frames omitted

检查了实体类和数据库发现没有什么错,原来是因为我的实体类里的groupId上用了/*@Column(name=“group_id”)注解,如下把该注解注释掉或者删除掉就可以了。

/* @Column(name="group_id")*/ private long groupId;

其他关于@ManyToMany(多对多关系)的使用可以去百度再看看,本人就不多说了。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java 设计模式以虹猫蓝兔的故事讲解单例模式

    Java 设计模式以虹猫蓝兔的故事讲解单例模式

    单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式
    2022-03-03
  • JAVA SPI机制详解使用方法

    JAVA SPI机制详解使用方法

    Java定义了一套JDBC的接口,但并未提供具体实现类,而是在不同云厂商提供的数据库实现包。这篇文章给大家介绍Java的SPI机制,感兴趣的朋友一起看看吧
    2022-07-07
  • Java如何实现简单的RPC框架

    Java如何实现简单的RPC框架

    这篇文章主要介绍了Java如何实现简单的RPC框架,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-07-07
  • spring boot使用自定义的线程池执行Async任务

    spring boot使用自定义的线程池执行Async任务

    这篇文章主要介绍了spring boot使用自定义的线程池执行Async任务的相关资料,需要的朋友可以参考下
    2018-02-02
  • SpringBoot使用validation-api实现对枚举类参数校验的方法

    SpringBoot使用validation-api实现对枚举类参数校验的方法

    这篇文章主要介绍了SpringBoot使用validation-api实现对枚举类参数校验,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • 最新IDEA 2022基于JVM极致优化 IDEA启动速度的方法

    最新IDEA 2022基于JVM极致优化 IDEA启动速度的方法

    这篇文章主要介绍了IDEA 2022最新版 基于 JVM极致优化 IDEA 启动速度,需要的朋友可以参考下
    2022-08-08
  • 详解Java事件编程的使用

    详解Java事件编程的使用

    Java事件在很多地方都可以使用,合理的使用事件编程,相比常规逻辑的编程,这可达到主次分明,让程序吞吐量即处理能力更强,改动更少,下面我们举一个例子说明如何使用Java使用,需要的朋友可以参考下
    2021-06-06
  • Java使用HttpClient实现文件下载

    Java使用HttpClient实现文件下载

    这篇文章主要为大家详细介绍了Java使用HttpClient实现文件下载,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • SpringBoot浅析缓存机制之Ehcache 2.x应用

    SpringBoot浅析缓存机制之Ehcache 2.x应用

    EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点。它是Hibernate中的默认缓存框架。Ehcache已经发布了3.1版本。但是本文的讲解基于2.x版本
    2022-08-08
  • Java实现三子棋游戏

    Java实现三子棋游戏

    这篇文章主要为大家详细介绍了Java实现三子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05

最新评论