如何使用@EmbeddedId在两个表之间映射?

编程入门 行业动态 更新时间:2024-10-10 17:28:46
本文介绍了如何使用@EmbeddedId在两个表之间映射?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

所以我这里是一个看起来像这样的图, 可以在此在此处答案中找到.

So what I have here is a diagram that looks like this, which can be found in this Answer Here.

+---------------+ +-------------------+ | PRODUCTS |-----< PRODUCT_VARIANTS | +---------------+ +-------------------+ | #product_id | | #product_id | | product_name | | #variant_id | +---------------+ | sku_id | | +-------------------+ | | +--------^--------+ +--------^--------+ | PRODUCT_OPTIONS |-----< VARIANT_VALUES | +-----------------+ +-----------------+ | #product_id | | #product_id | | #option_id | | #variant_id | +--------v--------+ | #option_id | | | value_id | +-----------------+ +--------v--------+ | OPTIONS | | +-----------------+ | | #option_id | | | option_name | | +-----------------+ | | | +-------^-------+ | | OPTION_VALUES |---------------+ +---------------+ | #option_id | | #value_id | | value_name | +---------------+

我设法在Spring应用程序中实现了整个图表,除了表VARIANT_VALUES

I managed to implement the whole diagram in my Spring app, except the table VARIANT_VALUES

问题在于设计表明表PRODUCT_OPTIONS,OPTION_VALUES和PRODUCT_VARIANTS具有复合ID(主键),我使用@EmbeddedId来实现 在其中三个上.

The problem is that the design suggests that the tables PRODUCT_OPTIONS, OPTION_VALUES and PRODUCT_VARIANTS have compound Ids (Primary Keys), which I implemented using @EmbeddedId on three of them.

喜欢如下 前任. //PRODUCT_VARIANTS

@Data @NoArgsConstructor @Entity @Table(name = "product_variants") public class ProductVariant { @EmbeddedId private ProductVariantId productVariantId; @NotNull private Double price; @MapsId("productId") @ManyToOne(fetch = FetchType.LAZY) private Product product; //other properties }

和//ProductVariantId

@Data @Embeddable public class ProductVariantId implements Serializable { @EqualsAndHashCode.Include private Long productVariantId; @EqualsAndHashCode.Include private Long productId; }

现在我需要使用VARIANT_VALUES

所以我尝试了这种方法//VariantValue

so I tried this approach //VariantValue

@Data @NoArgsConstructor @Entity @Table(name = "variant_values") public class VariantValue { @EmbeddedId private VariantValueId variantValueId; @MapsId("productVariantId") @ManyToOne(fetch = FetchType.LAZY) private ProductVariant productVariant; @MapsId("productOptionId") @ManyToOne(fetch = FetchType.LAZY) private ProductOption productOption; @MapsId("optionValueId") @ManyToOne(fetch = FetchType.LAZY) private OptionValue optionValue; }

//VariantValueId

@Embeddable @Data public class VariantValueId implements Serializable { @EqualsAndHashCode.Include @Embedded private ProductVariantId productVariantId; @EqualsAndHashCode.Include @Embedded private ProductOptionId productOptionId; @EqualsAndHashCode.Include @Embedded private OptionValueId optionValueId; }

但是最终创建了一个表,其中包含所有三个表中的每个ID,

but it ended up creating a table with each and every Id in all of the three tables,

当我在VariantValueId中添加@Embdded时,它会生成两列,而我找不到任何方法来排除一个值并使用另一个值,

When I add an @Embdded to VariantValueId it generates the two columns and I could not find any way to exclude one value and use the other,

所以生成的表现在看起来像这样//variant_values

so the generated table now looks something like this //variant_values

product_option_option_option_id [PK] product_option_ptoduct_product_id [PK] product_variant_ptoduct_product_id [PK] product_variant_ptoduct_variant_id [PK] product_value_option_option_id [PK] product_value_option_value_id [PK]

那么我该如何实现设计中建议的只有product_id [PK],variant_id [PK],option_id [PK]和value_id?

so how can I implement this to only have product_id [PK], variant_id [PK], option_id [PK] and value_id as the design suggests?

编辑1

我尝试了克里斯蒂安·贝科夫的方法

I tried Christian Beikov's Approach

@Data @NoArgsConstructor @EqualsAndHashCode(callSuper = true) @Entity @Table(name = "product_variants") public class ProductVariant extends UserDateAudit { @EmbeddedId @AttributeOverrides({ @AttributeOverride(name = "productVariantId", column = @Column(name = "variant_id")), @AttributeOverride(name = "productId", column = @Column(name = "product_id")) }) private ProductVariantId productVariantId; @NotNull private Double price; //many to many with product entity, option entity and optionValue entity @MapsId("productId") @ManyToOne(fetch = FetchType.LAZY) private Product product; @OneToMany(mappedBy = "productVariant", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private Set<VariantValue> variantValues; } @Data @Embeddable public class ProductVariantId implements Serializable { private Long productVariantId; private Long productId; } @Data @NoArgsConstructor @Entity @Table(name = "variant_values") public class VariantValue { @EmbeddedId @AttributeOverrides({ @AttributeOverride(name = "productVariantId", column = @Column(name = "variant_id")), @AttributeOverride(name = "productId", column = @Column(name = "product_id")) @AttributeOverride(name = "optionId", column = @Column(name = "option_id")), @AttributeOverride(name = "valueId", column = @Column(name = "value_id")) }) private VariantValueId variantValueId; @ManyToOne(fetch = FetchType.LAZY) @JoinColumns({ @JoinColumn(name = "variant_id", referencedColumnName = "variant_id", insertable = false, updatable = false), @JoinColumn(name = "product_id", referencedColumnName = "product_id", insertable = false, updatable = false) }) private ProductVariant productVariant; //other mappings

我遇到了以下错误

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaAuditingHandler': Cannot resolve reference to bean 'jpaMappingContext' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method failed; nested exception is org.hibernate.MappingException: Unable to find column with logical name: product_id in product_variants at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:342) ~[spring-beans-5.3.1.jar:5.3.1] at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:113) ~[spring-beans-5.3.1.jar:5.3.1] at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:691) ~[spring-beans-5.3.1.jar:5.3.1] at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:197) ~[spring-beans-5.3.1.jar:5.3.1] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1356) ~[spring-beans-5.3.1.jar:5.3.1] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1206) ~[spring-beans-5.3.1.jar:5.3.1] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:571) ~[spring-beans-5.3.1.jar:5.3.1] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:531) ~[spring-beans-5.3.1.jar:5.3.1] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.1.jar:5.3.1] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.1.jar:5.3.1] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.1.jar:5.3.1] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.1.jar:5.3.1] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944) ~[spring-beans-5.3.1.jar:5.3.1] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:925) ~[spring-context-5.3.1.jar:5.3.1] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:588) ~[spring-context-5.3.1.jar:5.3.1] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144) ~[spring-boot-2.4.0.jar:2.4.0] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:767) ~[spring-boot-2.4.0.jar:2.4.0] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) ~[spring-boot-2.4.0.jar:2.4.0] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:426) ~[spring-boot-2.4.0.jar:2.4.0] at org.springframework.boot.SpringApplication.run(SpringApplication.java:326) ~[spring-boot-2.4.0.jar:2.4.0] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1309) ~[spring-boot-2.4.0.jar:2.4.0] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1298) ~[spring-boot-2.4.0.jar:2.4.0] at com.ecommerce.ECommerceApplication.main(ECommerceApplication.java:10) ~[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.4.0.jar:2.4.0] Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method failed; nested exception is org.hibernate.MappingException: Unable to find column with logical name: product_id in product_variants at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1788) ~[spring-beans-5.3.1.jar:5.3.1] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:609) ~[spring-beans-5.3.1.jar:5.3.1] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:531) ~[spring-beans-5.3.1.jar:5.3.1] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.1.jar:5.3.1] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.1.jar:5.3.1] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.1.jar:5.3.1] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.1.jar:5.3.1] at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:330) ~[spring-beans-5.3.1.jar:5.3.1] ... 27 common frames omitted Caused by: org.hibernate.MappingException: Unable to find column with logical name: product_id in product_variants at org.hibernate.cfg.Ejb3JoinColumn.checkReferencedColumnsType(Ejb3JoinColumn.java:854) ~[hibernate-core-5.4.23.Final.jar:5.4.23.Final] at org.hibernate.cfg.BinderHelper.createSyntheticPropertyReference(BinderHelper.java:255) ~[hibernate-core-5.4.23.Final.jar:5.4.23.Final] at org.hibernate.cfg.ToOneFkSecondPass.doSecondPass(ToOneFkSecondPass.java:101) ~[hibernate-core-5.4.23.Final.jar:5.4.23.Final] at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processEndOfQueue(InFlightMetadataCollectorImpl.java:1823) ~[hibernate-core-5.4.23.Final.jar:5.4.23.Final] at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processFkSecondPassesInOrder(InFlightMetadataCollectorImpl.java:1767) ~[hibernate-core-5.4.23.Final.jar:5.4.23.Final] at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1655) ~[hibernate-core-5.4.23.Final.jar:5.4.23.Final] at org.hibernate.boot.model.process.spi.MetadataBuildingProcessplete(MetadataBuildingProcess.java:286) ~[hibernate-core-5.4.23.Final.jar:5.4.23.Final] at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1224) ~[hibernate-core-5.4.23.Final.jar:5.4.23.Final] at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1255) ~[hibernate-core-5.4.23.Final.jar:5.4.23.Final] at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58) ~[spring-orm-5.3.1.jar:5.3.1] at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.3.1.jar:5.3.1] at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[spring-orm-5.3.1.jar:5.3.1] at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630) ~[na:na] at java.base/java.lang.Thread.run(Thread.java:832) ~[na:na]

推荐答案

请尝试以下类似方法:

@Data @NoArgsConstructor @Entity @Table(name = "product_variants") public class ProductVariant { @EmbeddedId @AttributeOverrides({ @AttributeOverride(name = "productVariantId", column = @Column(name = "variant_id")), @AttributeOverride(name = "productId", column = @Column(name = "product_id")) }) private ProductVariantId productVariantId; @NotNull private Double price; @MapsId("productId") @ManyToOne(fetch = FetchType.LAZY) private Product product; //other properties } @Data @Embeddable public class ProductVariantId implements Serializable { @EqualsAndHashCode.Include private Long productVariantId; @EqualsAndHashCode.Include private Long productId; } @Data @NoArgsConstructor @Entity @Table(name = "variant_values") public class VariantValue { @EmbeddedId @AttributeOverrides({ @AttributeOverride(name = "productVariantId", column = @Column(name = "variant_id")), @AttributeOverride(name = "productId", column = @Column(name = "product_id")), @AttributeOverride(name = "optionId", column = @Column(name = "option_id")), @AttributeOverride(name = "valueId", column = @Column(name = "value_id")) }) private VariantValueId variantValueId; @ManyToOne(fetch = FetchType.LAZY) @JoinColumns({ @JoinColumn(name = "variant_id", referencedColumnName = "variant_id", insertable = false, updatable = false), @JoinColumn(name = "product_id", referencedColumnName = "product_id", insertable = false, updatable = false) }) private ProductVariant productVariant; @ManyToOne(fetch = FetchType.LAZY) @JoinColumns({ @JoinColumn(name = "option_id", referencedColumnName = "option_id", insertable = false, updatable = false), @JoinColumn(name = "product_id", referencedColumnName = "product_id", insertable = false, updatable = false) }) private ProductOption productOption; @ManyToOne(fetch = FetchType.LAZY) @JoinColumns({ @JoinColumn(name = "option_id", referencedColumnName = "option_id", insertable = false, updatable = false), @JoinColumn(name = "value_id", referencedColumnName = "value_id", insertable = false, updatable = false) }) private OptionValue optionValue; } @Embeddable @Data public class VariantValueId implements Serializable { @EqualsAndHashCode.Include private Long productVariantId; @EqualsAndHashCode.Include private Long productId; @EqualsAndHashCode.Include private Long optionId; @EqualsAndHashCode.Include private Long valueId; }

然后尝试以下方法:

@Data @NoArgsConstructor @Entity @Table(name = "product_variants") public class ProductVariant { @EmbeddedId @AttributeOverrides({ @AttributeOverride(name = "productVariantId", column = @Column(name = "variant_id")), @AttributeOverride(name = "productId", column = @Column(name = "product_id")) }) private ProductVariantId productVariantId; @NotNull private Double price; @ManyToOne(fetch = FetchType.LAZY) @JoinColum(name = "product_id", insertable = false, updatable = false) private Product product; //other properties }

更多推荐

如何使用@EmbeddedId在两个表之间映射?

本文发布于:2023-11-22 01:20:18,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1615414.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:如何使用   两个   EmbeddedId

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!