【问题标题】:Can Hibernate select a join table without including some rowsHibernate 可以在不包括某些行的情况下选择连接表吗
【发布时间】:2015-05-28 08:10:05
【问题描述】:

我使用 Hibernate 来控制我的数据库,我有 2 个表:

CREATE TABLE IF NOT EXISTS `User`(
    `id`        INT             NOT NULL    AUTO_INCREMENT,
    `name`      VARCHAR(255)    NOT NULL    DEFAULT '',
    `account`       VARCHAR(255)    NOT NULL    DEFAULT '',
    `password`      VARCHAR(255)    NOT NULL    DEFAULT '',
    PRIMARY KEY (`id`)
)

CREATE TABLE IF NOT EXISTS `Project` (
    `id`        INT             NOT NULL    AUTO_INCREMENT,
    `manager`   INT             NOT NULL,   
    `name`      VARCHAR(255)    NOT NULL    DEFAULT '', 
    PRIMARY KEY (`id`),
    FOREIGN KEY (`manager`) REFERENCES `User`(`id`)
)

我已经完成了映射:

用户:

// ... import code
@Entity
@Table
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    @Column
    private String name, account, password;

    @OneToMany(mappedBy = "manager")
    private List<Project> projects;

    public User() {
    }
    //  ... Getter & Setter code
}

项目:

// ... import code
@Entity
@Table
public class Project {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    @Column
    private String name;

    @ManyToOne
    @JoinColumn(name = "manager")
    private User manager;

    public Project () {
    }
    //  ... Getter & Setter code
}

我想知道是否可以在我选择项目时,项目将包含其经理数据但没有密码。

在其他方面,我希望我得到的每个项目都像这样(格式为 JSON):

{
    "id": 0,
    "name": "A test project",
    "manager": {
        "id": 0,
        "name": "John Smith"
        "accound": "user1",
        "password": null
    }
}

【问题讨论】:

    标签: java hibernate join


    【解决方案1】:

    1。投影

    projection 可用于限制要带入内存的字段,您可以获得除password 之外的所有字段的投影。

    2。懒惰

    另一种选择是在字段中添加惰性注释:

    @Basic(fetch = FetchType.LAZY)
    @Column(...)
    private String password;
    

    3。 HQL查询

    另一种方法是使用直接 HQL 查询并仅从 this answer 加载必填字段。

    【讨论】:

    • 1. 抱歉,我找不到任何方法可以让我忽略 Projection 2 中的 password 我试过 @ 987654325@,但它仍然显示密码3。如果密码像session.createQuery("Select new Project(id, name) from Project"),它可以工作。但是,我不知道它是如何变成像"Select new Project(id, name, creatorName) from Project" 这样的。
    【解决方案2】:

    如果你根本不想映射这个字段,你可以使用@Transient注解:

    @Transient
    private String password;
    

    如果您只是不想在将对象转换为特定 JSON 表示时显示此字段,那么这是一个数据表示问题,而不是 ORM 映射问题。将对象转换为 JSON 时应跳过此字段。实现取决于您使用的 JSON 转换器。例如,如果您使用 Jackson,那么您需要 @JsonIgnore 注释。

    【讨论】:

    • 抱歉,我认为 @Transient 不是我想要的。我想要的是当我选择用户表时我可以获得密码,当我选择项目表时,它不会给我密码。但是,当我选择用户表时,@Transient 将忽略密码。
    • 这是不可能的,因为在单个持久化上下文中对两个不同的实体(用户和项目)进行查询会导致两个不同的用户对象代表数据库中的一行,这违反了 ORM 原则身份。你真的应该考虑在你的演示级别上解决这个问题。
    猜你喜欢
    • 2018-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-15
    • 2014-07-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多