当前位置: 首页 > 知识库问答 >
问题:

一对一的关系不起作用

端木望
2023-03-14

Hibernate版本-5.3.4。最终版本,mysql连接器版本-8.0.12

我在帖子和帖子内容之间有一个@OneToOne关系:

帖子:

@Entity
@Table(name = "postsInfo")
public class PostsInfo {


    private long postId;
    private String title;
    private java.util.Date createDate;
    private Integer views;
    private Collection<Tags> tagsPost;
    private PostContent postContent;
    private PostImage postImage;
    private UserInfo userInfo;
    private List<PostsComments> postsComments;

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "post_id", unique = true, nullable = false)
    public long getPostId() {
        return postId;
    }

    @Basic
    @Column(name = "title", nullable = false)
    public String getTitle() {
        return title;
    }

    @Basic
    @Column(name = "createDate", nullable = false)
    public java.util.Date getCreateDate() {
        return createDate;
    }

    @Basic
    @Column(name = "views")
    public Integer getViews() {
        return views;
    }

    public PostsInfo(){}

    public PostsInfo(String title, List<Tags> tagsPost) {
        this.title = title;
        this.tagsPost = tagsPost;
        this.createDate = new Date();
    }

    @Fetch(FetchMode.SUBSELECT)
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "PostsTags",
            joinColumns = @JoinColumn(name = "post_id"),
            inverseJoinColumns = @JoinColumn(name = "tag_id"))
    public Collection<Tags> getTagsPost() {
        return tagsPost;
    }

    @OneToOne(cascade = CascadeType.ALL, mappedBy = "postsInfo", fetch = FetchType.LAZY, optional = false)
    public PostContent getPostContent() {
        return postContent;
    }

    @OneToOne(cascade = CascadeType.ALL, mappedBy = "postsInfo", orphanRemoval = true, fetch = FetchType.EAGER)
    public PostImage getPostImage() {
        return this.postImage;
    }

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "user_id", nullable = false)
    public UserInfo getUserInfo() {
        return userInfo;
    }

    @Cascade(org.hibernate.annotations.CascadeType.ALL)
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "postsInfo")
    public List<PostsComments> getPostsComments() {
        return postsComments;
    }
}

后内容:

   @Entity
@Table(name = "postContent")
public class PostContent {
    private long postId;
    private String content;
    private String subtitle;
    private List<PostInsideImages> postInsideImages;
    private PostsInfo postsInfo;

    @GenericGenerator(name = "generator", strategy = "foreign",
    parameters = @org.hibernate.annotations.Parameter(name = "property", value = "postsInfo"))
    @Id @GeneratedValue(generator = "generator")
    @Column(name = "post_id")
    public long getPostId() {
        return postId;
    }

    @Basic
    @Column(name = "content")
    public String getContent() {
        return content;
    }

    @Basic
    @Column(name = "subtitle")
    public String getSubtitle() {
        return subtitle;
    }

    public PostContent(){}

    public PostContent(String subtitle ,String content) {
        this.content = content;
        this.subtitle = subtitle;
    }

    public PostContent(String subtitle, String content, List<PostInsideImages> postInsideImages) {
        this.content = content;
        this.subtitle = subtitle;
        this.postInsideImages = postInsideImages;
    }

    @OneToMany( cascade = CascadeType.ALL, mappedBy = "postContent")
    @LazyCollection(LazyCollectionOption.FALSE)
    public List<PostInsideImages> getPostInsideImages() {
        return postInsideImages;
    }

    @OneToOne(fetch = FetchType.LAZY, optional = false)
    @PrimaryKeyJoinColumn
    public PostsInfo getPostsInfo() {
        return postsInfo;
    }
}

我一直试图让PostContent的负载变懒,但没有什么工作。

我添加到@OneToOne关系提取=FetchType. LAZY,可选=false,

我加入了冬眠。cfg。xml此属性:

<property name="hibernate.enhancer.enableLazyInitialization">true</property>

这个maven插件:

<plugin>
                <groupId>org.hibernate.orm.tooling</groupId>
                <artifactId>hibernate-enhance-maven-plugin</artifactId>
                <version>5.3.4.Final</version>
                <executions>
                    <execution>
                        <configuration>
                            <failOnError>true</failOnError>
                            <enableLazyInitialization>true</enableLazyInitialization>
                        </configuration>
                        <goals>
                            <goal>enhance</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

要启用字节码增强,

添加@LazyToOne(LazyToOneOption.NO_PROXY)

我试图改变Hibernate版本(5.2, 5.1.10, 5.3.3, 5.3.1),但仍然Hibernate加载帖子内容渴望。

我的代码得到一个职位:

@Override
public PostsInfo getCommonPost(long id){
    return session.find(PostsInfo.class, id);
}

Hibernate sql:

    Hibernate: select postsinfo0_.post_id as post_id1_9_0_, postsinfo0_.createDate as createDa2_9_0_, postsinfo0_.title as title3_9_0_, postsinfo0_.user_id as user_id5_9_0_, postsinfo0_.views as views4_9_0_, postimage1_.post_id as post_id1_6_1_, postimage1_.image_l as image_l2_6_1_, postimage1_.image_m as image_m3_6_1_, postimage1_.image_s as image_s4_6_1_ from postsInfo postsinfo0_ left outer join postImage postimage1_ on postsinfo0_.post_id=postimage1_.post_id where postsinfo0_.post_id=?
Hibernate: select postconten0_.post_id as post_id1_5_0_, postconten0_.content as content2_5_0_, postconten0_.subtitle as subtitle3_5_0_ from postContent postconten0_ where postconten0_.post_id=?
Hibernate: select postinside0_.post_id as post_id3_7_0_, postinside0_.image_id as image_id1_7_0_, postinside0_.image_id as image_id1_7_1_, postinside0_.image as image2_7_1_, postinside0_.post_id as post_id3_7_1_ from postInsideImages postinside0_ where postinside0_.post_id=?
Hibernate: select tagspost0_.post_id as post_id1_10_0_, tagspost0_.tag_id as tag_id2_10_0_, tags1_.tag_id as tag_id1_15_1_, tags1_.description as descript2_15_1_, tags1_.name as name3_15_1_ from PostsTags tagspost0_ inner join Tags tags1_ on tagspost0_.tag_id=tags1_.tag_id where tagspost0_.post_id=?

我能做些什么来得到一个懒散的负载?

共有2个答案

薛兴言
2023-03-14

你的数据库里有设计的味道。因为您没有与父表PK共享子表PK。一对一协会始终共享PK。在您的情况下,PostContent类的postId应该仅由PostsInfo类的postId映射。但在PostContent中,PostsInfo有单独的PK和FK,这对于一对一的关系来说应该是一样的,hibernate也提倡这一点。因为如果你有单独的FK和PK,那么一个PostsInfo可能有多个PostContent。请浏览以下链接,因为其中解释的场景与您的场景非常相似。

https://vladmihalcea.com/the-best-way-to-map-a-onetoone-relationship-with-jpa-and-hibernate/

寇桐
2023-03-14

@Danil Eltsov,这意味着你会为相关的集合做另一个查询。无论如何,懒负载都会生成另一个查询。

 类似资料:
  • 我正在用Laravel8开发一个应用程序,我遇到了非常奇怪的行为。 我有一个叫做“组织”的模型,这个组织有很多用户(来自捷流的模型)。 我像往常一样做了关系: 在组织模式中: 在用户模型中: 我在用户表上有一个名为Organization_id的字段,在迁移中声明如下: 我检查了数据库,所有的东西都填进去了,没有空值。 预期结果:如果我打电话 我将获取组织对象。 实际结果:我收到一个Veeeery

  • 让我们来理解MS Access中的一对一关系。 这种关系用于将一个表中的一条记录与另一个表中的一条记录相关联。 现在转到 数据库工具 选项卡。 点击关系 选项。然后选择和,然后单击添加按钮将它们添加到视图中,然后关闭显示表格对话框。如下图所示 - 要创建这两个表之间的关系,请使用鼠标,然后单击并按住Employees 中的字段,然后将该字段拖放到要关联的字段上,方法是将鼠标悬停在tblHRData

  • 问题内容: 我正在尝试在MySQL数据库中实现“一对一”的关系。例如,假设我有一个Users表和一个Accounts表。我想确保一个用户只能拥有一个帐户。每个用户只能有一个帐户。 我找到了两个解决方案,但是不知道该使用什么,还有其他选择。 第一个解决方案: 在此示例中,我在指向用户主键的帐户中定义外键。然后,我使外键成为唯一键,因此帐户中不能有两个相同的用户。要联接表,我将使用以下查询: 第二种解

  • 我试图在MySQL数据库中实现“一对一”的关系。例如,假设我有一个Users表和一个Accounts表。我想确保一个用户只能有一个帐户。每个用户只能有一个帐户。 我找到了两个解决方案,但不知道该用什么,还有其他的选择。 在本例中,我定义了指向用户中主键的帐户中的外键。然后我使外键唯一,所以帐户中不能有两个相同的用户。要联接表,我将使用以下查询: null 如果我将这些解决方案中的任何一个导入到My

  • 问题内容: 我将satchmo应用程序的管理员放在一起。Satchmo使用OneToOne关系来扩展基本模型,我想在一页上进行全部编辑。 可以将OneToOne关系作为内联吗?如果不是,最好的方法是在管理员的给定页面中添加一些字段,这些字段最终将保存到OneToOne关系中? 例如: 我为管理员尝试了此操作,但是它不起作用,并且似乎期望使用外键: 引发此错误: 这样做的唯一方法是自定义表单吗? 编