概述
1、建表, 在多的一方创建外键关联
# 产品 - 多的一方
drop table if exists product;
create table product(
id varchar(64) primary key
,name varchar(20)
,product_type_id varchar(64)
# 添加外键映射
,constraint fk_product_id foreign key (product_type_id) references product_type(id)
) engine InnoDB charset 'utf8';
# 产品类型名称 - one的一方
create table product_type(
id varchar(64) primary key
,name varchar(20)
) engine InnoDB charset 'utf8';
2、做实体映射
many一方的实体映射代码如下:
package com.jiang.jpa.otm.entity;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
package com.jiang.jpa.otm.entity;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
/**
*
* many的一方
*
* @author Luosj
*
* @date 2020/2/16 5:09 PM
*/
@Entity
@Table(name = "product")
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class Product{
@Id
private String id;
private String name;
@ManyToOne
// @Column(name="product_type_id") // 多的一方不能使用@Column来配置外键列名
@JoinColumn(name = "product_type_id")
private ProductType productType;
@Override
public String toString() {
return "{id:"+this.getId()+",name:"+this.getName()+"}";
}
}
/**
* @author Luosj
* @desc: from spring-data-jpa-demo
*/
One一方的实体如下:
package com.jiang.jpa.otm.entity;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
/**
*
* one的一方
*
* @author Luosj
*
* @date 2020/2/16 5:12 PM
*/
@Entity
@Table(name = "product_type")
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class ProductType{
@Id
private String id;
private String name;
}
实体映射 - DAO接口
package com.jiang.jpa.otm.dao;
import com.jiang.jpa.otm.entity.Product;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
/**
* @author Luosj
* @date 2020/2/16 5:28 PM
*/
@Repository
public interface ProductDao extends JpaRepository<Product, String> {
}
package com.jiang.jpa.otm.dao;
import com.jiang.jpa.otm.entity.ProductType;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
/**
* @author Luosj
* @date 2020/2/16 5:29 PM
*/
@Repository
public interface ProductTypeDao extends JpaRepository<ProductType, String> {
}
3、数据初始化操作
数据初始化过程需要保证One的一方存在数据, 才能实现多的一方数据存储
这里展示的是正确的代码
@Autowired
private ProductDao productDao;
@Autowired
private ProductTypeDao productTypeDao;
/**
*
* 数据初始化测试 - 先保证一的一方存在数据, 才能存储多的一方
*
*/
@Test
public void init(){
// one
ProductType type = new ProductType();
type.setId(String.valueOf(System.currentTimeMillis()));
type.setName("水果3");
// many
Product p1 = new Product(UUID.randomUUID().toString(), "苹果", type);
Product p2 = new Product(UUID.randomUUID().toString(), "梨子", type);
Product p3 = new Product(UUID.randomUUID().toString(), "香蕉", type);
// persistence
productTypeDao.save(type);
productDao.save(p1);
productDao.save(p2);
productDao.save(p3);
}
错误的代码
@Test
public void errorInit(){
// one
ProductType type = new ProductType();
type.setId(String.valueOf(System.currentTimeMillis()));
type.setName("水果3");
// many
Product p1 = new Product(UUID.randomUUID().toString(), "苹果", type);
Product p2 = new Product(UUID.randomUUID().toString(), "梨子", type);
Product p3 = new Product(UUID.randomUUID().toString(), "香蕉", type);
// persistence
productDao.save(p1);
productDao.save(p2);
productDao.save(p3);
productTypeDao.save(type);
}
执行这段代码会抛出的异常:
Caused by: javax.persistence.EntityNotFoundException: Unable to find com.jiang.jpa.otm.entity.ProductType with id 1581848679583
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$JpaEntityNotFoundDelegate.handleEntityNotFound(EntityManagerFactoryBuilderImpl.java:163)
at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:216)
at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:332)
at org.hibernate.event.internal.DefaultLoadEventListener.doOnLoad(DefaultLoadEventListener.java:108)
at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:74)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:118)
at org.hibernate.internal.SessionImpl.fireLoadNoChecks(SessionImpl.java:1168)
at org.hibernate.internal.SessionImpl.internalLoad(SessionImpl.java:1033)
at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:687)
at org.hibernate.type.EntityType.resolve(EntityType.java:464)
at org.hibernate.type.ManyToOneType.resolve(ManyToOneType.java:240)
at org.hibernate.type.EntityType.resolve(EntityType.java:457)
at org.hibernate.type.EntityType.replace(EntityType.java:358)
at org.hibernate.type.AbstractType.replace(AbstractType.java:164)
at org.hibernate.type.TypeHelper.replace(TypeHelper.java:204)
at org.hibernate.event.internal.DefaultMergeEventListener.copyValues(DefaultMergeEventListener.java:488)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:241)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:318)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:172)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:70)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:108)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:775)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:762)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:314)
at com.sun.proxy.$Proxy70.merge(Unknown Source)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:557)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:371)
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:204)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:657)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:621)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:605)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:366)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:99)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
... 71 more
最后
以上就是生动水壶为你收集整理的JPA单向多对一实体映射的全部内容,希望文章能够帮你解决JPA单向多对一实体映射所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复