因休眠而丢失 - OneToMany 导致被多次拉回

发布于 2024-09-02 22:41:56 字数 2324 浏览 7 评论 0原文

我有这个数据库设计:

CREATE TABLE report (
    ID          MEDIUMINT PRIMARY KEY NOT NULL AUTO_INCREMENT,
    user        MEDIUMINT NOT NULL,
    created     TIMESTAMP NOT NULL,
    state       INT NOT NULL,
    FOREIGN KEY (user) REFERENCES user(ID) ON UPDATE CASCADE ON DELETE CASCADE
);


CREATE TABLE reportProperties (
    ID          MEDIUMINT NOT NULL, 
    k           VARCHAR(128) NOT NULL,
    v           TEXT NOT NULL,
    PRIMARY KEY(
        ID, k
    ),
    FOREIGN KEY (ID) REFERENCES report(ID) ON UPDATE CASCADE ON DELETE CASCADE
);

和这个 Hibernate 标记:

@Table(name="report")
@Entity(name="ReportEntity")
public class ReportEntity extends Report{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="ID")
    private Integer ID;
    @Column(name="user")
    private Integer user;
    @Column(name="created")
    private Timestamp created;
    @Column(name="state")
    private Integer state = ReportState.RUNNING.getLevel();

    @OneToMany(mappedBy="pk.ID", fetch=FetchType.EAGER)
    @JoinColumns(
            @JoinColumn(name="ID", referencedColumnName="ID")
    )
    @MapKey(name="pk.key")
    private Map<String, ReportPropertyEntity> reportProperties = new HashMap<String, ReportPropertyEntity>();
}

并且

@Table(name="reportProperties")
@Entity(name="ReportPropertyEntity")
public class ReportPropertyEntity extends ReportProperty{

    @Embeddable
    public static class ReportPropertyEntityPk implements Serializable{
        /**
         * long#serialVersionUID
         */
        private static final long serialVersionUID = 2545373078182672152L;
        @Column(name="ID")
        protected int ID;
        @Column(name="k")
        protected String key;
    }

    @EmbeddedId
    protected ReportPropertyEntityPk pk = new ReportPropertyEntityPk();

    @Column(name="v")
    protected String value;
}

我已经插入了该报告的报告和 4 个属性。现在,当我执行此操作时:

this.findByCriteria(
                        Order.asc("created"), 
                        Restrictions.eq("user", user.getObject(UserField.ID))
                    )
                );

我返回报告 4 次,而不是只返回一次包含 4 个属性的 Map。说实话,我不太擅长 Hibernate,更喜欢直接 SQL,但我必须学习,但我可以看不出有什么问题......?

有什么建议吗?

I have this DB design:

CREATE TABLE report (
    ID          MEDIUMINT PRIMARY KEY NOT NULL AUTO_INCREMENT,
    user        MEDIUMINT NOT NULL,
    created     TIMESTAMP NOT NULL,
    state       INT NOT NULL,
    FOREIGN KEY (user) REFERENCES user(ID) ON UPDATE CASCADE ON DELETE CASCADE
);


CREATE TABLE reportProperties (
    ID          MEDIUMINT NOT NULL, 
    k           VARCHAR(128) NOT NULL,
    v           TEXT NOT NULL,
    PRIMARY KEY(
        ID, k
    ),
    FOREIGN KEY (ID) REFERENCES report(ID) ON UPDATE CASCADE ON DELETE CASCADE
);

and this Hibernate Markup:

@Table(name="report")
@Entity(name="ReportEntity")
public class ReportEntity extends Report{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="ID")
    private Integer ID;
    @Column(name="user")
    private Integer user;
    @Column(name="created")
    private Timestamp created;
    @Column(name="state")
    private Integer state = ReportState.RUNNING.getLevel();

    @OneToMany(mappedBy="pk.ID", fetch=FetchType.EAGER)
    @JoinColumns(
            @JoinColumn(name="ID", referencedColumnName="ID")
    )
    @MapKey(name="pk.key")
    private Map<String, ReportPropertyEntity> reportProperties = new HashMap<String, ReportPropertyEntity>();
}

and

@Table(name="reportProperties")
@Entity(name="ReportPropertyEntity")
public class ReportPropertyEntity extends ReportProperty{

    @Embeddable
    public static class ReportPropertyEntityPk implements Serializable{
        /**
         * long#serialVersionUID
         */
        private static final long serialVersionUID = 2545373078182672152L;
        @Column(name="ID")
        protected int ID;
        @Column(name="k")
        protected String key;
    }

    @EmbeddedId
    protected ReportPropertyEntityPk pk = new ReportPropertyEntityPk();

    @Column(name="v")
    protected String value;
}

And i have inserted on Report and 4 Properties for that report. Now when i execute this:

this.findByCriteria(
                        Order.asc("created"), 
                        Restrictions.eq("user", user.getObject(UserField.ID))
                    )
                );

I get back the report 4 times, instead of just the once with a Map with the 4 properties in. I'm not great at Hibernate to be honest, prefer straight SQL but I must learn, but i can't see what it is that is wrong.....?

Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

二货你真萌 2024-09-09 22:41:56

我不知道你的问题的答案,但你可以用另一种方式来做这件事并取消整个 ReportPropertyEntity 类:

@CollectionOfElements
@JoinTable(name = "reportProperties", joinColumns = { @JoinColumn(name = "id") })
@MapKey(columns = { @Column(name = "`key`") })
@Column(name = "`value`", length = 131070, nullable = false)
private Map<String, String> reportProperties = new HashMap<String, String>();

i do not know the answer to your question, but you could do this another way and do away with that whole ReportPropertyEntity class :

@CollectionOfElements
@JoinTable(name = "reportProperties", joinColumns = { @JoinColumn(name = "id") })
@MapKey(columns = { @Column(name = "`key`") })
@Column(name = "`value`", length = 131070, nullable = false)
private Map<String, String> reportProperties = new HashMap<String, String>();
总以为 2024-09-09 22:41:56

尝试在您的条件/查询中使用它:

setResultTransformer(DistinctRootEntityResultTransformer.INSTANCE);

这适用于您的所有表。无需修改映射。

Try using this on your criteria/query:

setResultTransformer(DistinctRootEntityResultTransformer.INSTANCE);

This will work for all your tables. No need to modify mappings.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文