【问题标题】:How to create One-to-Many and Many-to-One Relationship from one class to another class in Java/IntelliJ如何在 Java/IntelliJ 中创建从一个类到另一个类的一对多和多对一关系
【发布时间】:2018-04-30 12:19:33
【问题描述】:

我已经研究过如何解决这个问题,但没有一个对我有用。我知道我不完全理解它是如何工作的——这正是重点,但有时我不得不停下来寻求帮助/澄清。

我正在从事一个业余项目(并且正在锻炼我的编程技能)。请注意,我是初级水平。

我正在尝试创建两个类,其中一个类具有多个一对一关系的字段。只有两个字段具有 1 到 M 关系和 M 到 M 关系。 “狗”类有一个名为图片的字段,它将与“图片”类是 1 到 M 的关系。在我的一生中,每次执行代码时都会遇到问题。我已经尝试了几种使它工作的方法——例如使类可序列化、将一个字段映射到另一个字段,反之亦然,使用 CascadeType 等等。我开始意识到也许我不太了解它在 Java 中是如何工作的(我使用的是 IntelliJ),尽管我理解了它的概念。

我已阅读并尝试使用的文章仅举几例:

Entity Framework one-to-many and many-to-many relationship

Multiple 1:many relationship in Hibernate

Java JPA one to many

http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/#entity-mapping-association

Hibernate One to Many and Many to One Relation

我有一种感觉,我真的很接近我想要做的事情......但我似乎忽略了一些东西,严重

我的数据库的意图:

我正在使 Dog 表中的每一行都有自己的名字、体重等。 每行(狗)将分配给他们许多图片。它们将以数据库中的 URL 地址的形式出现,我计划使用 Spring 框架对其进行调用。我找到了 Cloudinary,并认为我可以尝试用我的代码来实现他们的代码。我的这个副项目是改进一个现有的、正在工作的实验室救援组织,它拥有我见过的最基本的网站。

这是我的代码:

狗桌/类

package com.claudiazeledon.LuckyLabsRescue.models;

import org.hibernate.annotations.Target;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Collection;
import java.util.Set;

@Entity
public class Dog{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column
    private String name;

    @Column
    private Integer weight;

    @Column
    private Integer age;

    @Column
    private Gender gender;

    @Column
    private String color;

    @OneToOne
    private Temperament temperament;

    @OneToOne
    private Availability availability;

    @OneToOne
    private Health health;

    @OneToMany
    @JoinColumn(name = "picture_dp")
    private Set<Picture> getPictures;

    public Dog() {
    }

    public Dog(int id, String name, Integer weight, Integer age, Gender gender, String color, Temperament temperament, Availability availability, Health health, Set<Picture> getPictures) {
        this.id = id;
        this.name = name;
        this.weight = weight;
        this.age = age;
        this.gender = gender;
        this.color = color;
        this.temperament = temperament;
        this.availability = availability;
        this.health = health;
        this.getPictures = getPictures;
    }

    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;
    }

    public Integer getWeight() {
        return weight;
    }

    public void setWeight(Integer weight) {
        this.weight = weight;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Gender getGender() {
        return gender;
    }

    public void setGender(Gender gender) {
        this.gender = gender;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public Temperament getTemperament() {
        return temperament;
    }

    public void setTemperament(Temperament temperament) {
        this.temperament = temperament;
    }

    public Availability getAvailability() {
        return availability;
    }

    public void setAvailability(Availability availability) {
        this.availability = availability;
    }

    public Health getHealth() {
        return health;
    }

    public void setHealth(Health health) {
        this.health = health;
    }

    public Set<Picture> getGetPictures() {
        return getPictures;
    }

    public void setGetPictures(Set<Picture> getPictures) {
        this.getPictures = getPictures;
    }
}

图片表/类

package com.claudiazeledon.LuckyLabsRescue.models;

import javax.persistence.*;
import java.net.URL;

@Entity
@Table(name = "picture")
public class Picture{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @ManyToOne
    @JoinColumn(name = "picture_dp", insertable = false, updatable = false)
    private URL pictureURL;

//    @ManyToOne
//    @JoinColumn(name = "pictureId")
//    @MapsId("pictureId")
//    private Dog dogImage;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public URL getPictureURL() {
        return pictureURL;
    }

    public void setPictureURL(URL pictureURL) {
        this.pictureURL = pictureURL;
    }

}

来自 IntelliJ 的错误消息

2017-11-16 15:20:35.300  INFO 24180 --- [  restartedMain] org.hibernate.Version                    : HHH000412: Hibernate Core {5.0.12.Final}
2017-11-16 15:20:35.301  INFO 24180 --- [  restartedMain] org.hibernate.cfg.Environment            : HHH000206: hibernate.properties not found
2017-11-16 15:20:35.302  INFO 24180 --- [  restartedMain] org.hibernate.cfg.Environment            : HHH000021: Bytecode provider name : javassist
2017-11-16 15:20:35.418  INFO 24180 --- [  restartedMain] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
2017-11-16 15:20:35.518  INFO 24180 --- [  restartedMain] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.PostgreSQLDialect
2017-11-16 15:20:35.623  INFO 24180 --- [  restartedMain] o.h.e.j.e.i.LobCreatorBuilderImpl        : HHH000424: Disabling contextual LOB creation as createClob() method threw error : java.lang.reflect.InvocationTargetException
2017-11-16 15:20:35.625  INFO 24180 --- [  restartedMain] org.hibernate.type.BasicTypeRegistry     : HHH000270: Type registration [java.util.UUID] overrides previous : org.hibernate.type.UUIDBinaryType@673c77b3
2017-11-16 15:20:35.766  WARN 24180 --- [  restartedMain] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: @OneToOne or @ManyToOne on com.claudiazeledon.LuckyLabsRescue.models.Picture.pictureURL references an unknown entity: java.net.URL
2017-11-16 15:20:35.771  INFO 24180 --- [  restartedMain] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2017-11-16 15:20:35.782  INFO 24180 --- [  restartedMain] utoConfigurationReportLoggingInitializer : 

Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2017-11-16 15:20:35.792 ERROR 24180 --- [  restartedMain] o.s.boot.SpringApplication               : Application startup failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: @OneToOne or @ManyToOne on com.claudiazeledon.LuckyLabsRescue.models.Picture.pictureURL references an unknown entity: java.net.URL
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1078) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:857) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
    at com.claudiazeledon.LuckyLabsRescue.LuckyLabsRescueApplication.main(LuckyLabsRescueApplication.java:10) [classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_144]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_144]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_144]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_144]
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-1.5.8.RELEASE.jar:1.5.8.RELEASE]
Caused by: org.hibernate.AnnotationException: @OneToOne or @ManyToOne on com.claudiazeledon.LuckyLabsRescue.models.Picture.pictureURL references an unknown entity: java.net.URL
    at org.hibernate.cfg.ToOneFkSecondPass.doSecondPass(ToOneFkSecondPass.java:97) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processEndOfQueue(InFlightMetadataCollectorImpl.java:1786) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processFkSecondPassesInOrder(InFlightMetadataCollectorImpl.java:1730) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1617) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:278) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:847) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:874) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) ~[spring-orm-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:353) ~[spring-orm-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:370) ~[spring-orm-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:359) ~[spring-orm-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    ... 21 common frames omitted

【问题讨论】:

    标签: java hibernate jpa intellij-idea one-to-many


    【解决方案1】:

    看看这个例子。您对一对多关系的怀疑将很清楚。例如取 2 个实体。 CustomerEntity.javaProductEntity.java。在CustomerEntity.java添加

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "customer") private Product product;

    并在ProductEntity.java 中添加字段。

    @ManyToOne(fetch = FetchType.LAZY, optional = false) @JoinColumn(name = "customer_id", nullable = false) @JsonIgnore private Customer customer;

    使实体类中的字段和implements Serializable 接口的getter setter。如果您使用的是 json 数据类型,则可以添加 @JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" })

    【讨论】:

      【解决方案2】:

      您在pictureUrl 上放置了@ManyToOne 关系:

      @ManyToOne
      @JoinColumn(name = "picture_dp", insertable = false, updatable = false)
      private URL pictureURL;
      

      实体之间建立了关系,但 URL 不是实体。

      最简单的解决方案是删除该字段上的 @ManyToOne@JoinColumn 注释,并将它们替换为常规的 @Column 注释。

      @Column
      private URL pictureURL;
      

      【讨论】:

      • 天哪!这样可行!但是,我发现自己想知道它是否会成功地将 pictureURL 分配给 dog 表中的主 id?
      • @Claudia 是的,您的Dog 实体将链接到多个Picture 实体,因为您在Dog 类中使用了@ManyToOne 注释。 pictureUrl 也将被链接,因为它位于 Picture 类中。只要确保在其上放置一个常规的@Column 注释即可。如果它解决了您的问题,请记住接受答案:)
      • 啊,我应该在Dog 类中使用@ManyToOne 而不是@OneToMany 注释?我认为@OneToMany 意味着一只狗会有很多照片,而不是相反。一旦我的问题得到解决,我一定会接受!我现在正在测试。
      • @Claudia 在考虑这些注释时,第一个术语是指类,第二个是指字段。示例:@ManyToOne 位于 picture 类内的 Dog 字段上,表示:多只狗到一张图片。在您的Dog 课程中,您的图片上有一个@OneToMany 注释,这意味着:一张狗到多张图片,我认为这就是您想要的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-13
      • 1970-01-01
      • 1970-01-01
      • 2019-08-04
      相关资源
      最近更新 更多