Java 如何用连接来保持实体?

Java 如何用连接来保持实体?,java,spring,postgresql,hibernate,jpa,Java,Spring,Postgresql,Hibernate,Jpa,我对如何使用列的联接在db中保存条目感到困惑。我有@实体吼叫 @XmlRootElement @XmlAccessorType(value = XmlAccessType.FIELD) @Entity @Table(name = "psc_users") @NamedQuery(name = "User.findAll", query = "SELECT u FROM User u") public class User impleme

我对如何使用列的联接在db中保存条目感到困惑。我有@实体吼叫

@XmlRootElement
@XmlAccessorType(value = XmlAccessType.FIELD)
@Entity
@Table(name = "psc_users")
@NamedQuery(name = "User.findAll", query = "SELECT u FROM User u")
public class User implements Serializable {
    private static final long serialVersionUID = 8885916014620036457L;

    @Id
    private static final String SEQUENCE_NAME = "psc_users_user_id_seq";
    @Id
    @GeneratedValue(generator = "UseExistingOrGenerateIdGenerator",
            strategy = GenerationType.SEQUENCE)
    @GenericGenerator(name = "UseExistingOrGenerateIdGenerator",
            strategy = "com.psc.util.UseExistingOrGenerateIdGenerator",
            parameters = {
                    @org.hibernate.annotations.Parameter(name = "sequence", value = SEQUENCE_NAME)
            }
    )
    @Column(name = "USER_ID")
    private Long userId;

    @Column(name = "DEF", length = 30)
    private String def;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "DEL_DATE")
    private Date delDate;

    @Column(name = "DISPLAY_DEF", length = 60)
    private String displayDef;

    @Column(name = "EMAIL", length = 60)
    private String email;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "NAVI_DATE")
    private Date naviDate;

    @Column(name = "NAVI_USER")
    private String naviUser;

    @Column(name = "PHONE", length = 30)
    private String phone;

    @Column(name = "PWD", length = 40)
    private String pwd;

    //bi-directional many-to-one association to Branch
    @ManyToOne(cascade = CascadeType.MERGE)
    @JoinColumn(name = "BRNC_BRNC_ID", nullable = false)
    private Branch pscBranch;

    public Long getBrncBrncId() {
        return brncBrncId;
    }

    public void setBrncBrncId(Long brncBrncId) {
        this.brncBrncId = brncBrncId;
    }

    @Column(name = "BRNC_BRNC_ID", insertable = false, updatable = false)
    private Long brncBrncId;
    //bi-directional many-to-one association to User
    @ManyToOne(cascade = CascadeType.MERGE)
    @JoinColumn(name = "CURATOR_USER_ID")
    private User pscUser;


    public Long getCuratorUserId() {
        return curatorUserId;
    }

    public void setCuratorUserId(Long curatorUserId) {
        this.curatorUserId = curatorUserId;
    }

    @Column(name = "CURATOR_USER_ID", insertable = false, updatable = false)
    private Long curatorUserId;

    public User() {
    }

    public Long getUserId() {
        return this.userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public String getDef() {
        return this.def;
    }

    public void setDef(String def) {
        this.def = def;
    }

    public Date getDelDate() {
        return this.delDate;
    }

    public void setDelDate(Date delDate) {
        this.delDate = delDate;
    }

    public String getDisplayDef() {
        return this.displayDef;
    }

    public void setDisplayDef(String displayDef) {
        this.displayDef = displayDef;
    }

    public String getEmail() {
        return this.email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Date getNaviDate() {
        return this.naviDate;
    }

    public void setNaviDate(Date naviDate) {
        this.naviDate = naviDate;
    }

    public String getNaviUser() {
        return this.naviUser;
    }

    public void setNaviUser(String naviUser) {
        this.naviUser = naviUser;
    }

    public String getPhone() {
        return this.phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getPwd() {
        return this.pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    public Branch getPscBranch() {
        return this.pscBranch;
    }

    public void setPscBranch(Branch pscBranch) {
        this.pscBranch = pscBranch;
    }

    public User getPscUser() {
        return this.pscUser;
    }

    public void setPscUser(User pscUser) {
        this.pscUser = pscUser;
    }

}
如果我保存用户实例时没有字段pscUser(此处为null),但存在具有正确值的有效CuratorUserId,那么我最终会遇到数据库中CuratorUserId为空的情况。如果您查看代码,就会看到这些绑定字段

  @ManyToOne(cascade = CascadeType.MERGE)
    @JoinColumn(name = "CURATOR_USER_ID")
    private User pscUser;


    @Column(name = "CURATOR_USER_ID", insertable = false, updatable = false)
    private Long curatorUserId;
保存用户的代码

repositoryUser.save(user);
这是我在调试器中看到的

这是我在保存用户后在数据库中看到的


很抱歉我提出了一个愚蠢的问题,但我遇到了一个不同的行为,我的项目中有一个以另一种方式运行的代码。我不想搜索实际的另一个用户(curator)来保存我的用户,因为查询开销很大

curetorUserId字段上的@Column注释具有属性 insertable=false和Updateable=false,这意味着在插入和更新期间忽略其值


您可以将这些属性更改为true(但它可能会在其他地方破坏您的应用程序),也可以使用EntityManager.getReference填写pscUser字段,这只会创建一个代理,实际上不会生成对数据库的查询。

您的映射应如下所示:

@XmlRootElement
@XmlAccessorType(value = XmlAccessType.FIELD)
@Entity
@Table(name = "psc_users")
@NamedQuery(name = "User.findAll", query = "SELECT u FROM User u")
public class User implements Serializable {
    private static final long serialVersionUID = 8885916014620036457L;

    @Id
    private static final String SEQUENCE_NAME = "psc_users_user_id_seq";
    @Id
    @GeneratedValue(generator = "UseExistingOrGenerateIdGenerator",
            strategy = GenerationType.SEQUENCE)
    @GenericGenerator(name = "UseExistingOrGenerateIdGenerator",
            strategy = "com.psc.util.UseExistingOrGenerateIdGenerator",
            parameters = {
                    @org.hibernate.annotations.Parameter(name = "sequence", value = SEQUENCE_NAME)
            }
    )
    @Column(name = "USER_ID")
    private Long userId;

    @Column(name = "DEF", length = 30)
    private String def;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "DEL_DATE")
    private Date delDate;

    @Column(name = "DISPLAY_DEF", length = 60)
    private String displayDef;

    @Column(name = "EMAIL", length = 60)
    private String email;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "NAVI_DATE")
    private Date naviDate;

    @Column(name = "NAVI_USER")
    private String naviUser;

    @Column(name = "PHONE", length = 30)
    private String phone;

    @Column(name = "PWD", length = 40)
    private String pwd;

    //bi-directional many-to-one association to Branch
    @ManyToOne(cascade = CascadeType.MERGE)
    @JoinColumn(name = "BRNC_BRNC_ID", nullable = false)
    private Branch pscBranch;

    //bi-directional many-to-one association to User
    @ManyToOne(cascade = CascadeType.MERGE)
    @JoinColumn(name = "CURATOR_USER_ID")
    private User pscUser;

    public User() {

    }
}

你需要从对象的角度来思考。只有将pscUser引用设置为用户实例时,才会在数据库中设置FK。如果这是一个现有用户,那么您需要设置对现有持久实体的引用。

真正的答案是,我有两点可以保存和更新我的实体。请查看此

谢谢您的回答,但我不明白为什么它希望在对象上有参考?由于inseatable=false和updateable=false??如果我指定的pscUser无效,会是什么情况(这不是由db组成的,但他的id是由db组成的?在我看来,这不会带来任何不良影响,有了这个属性,用户类中有两个字段,它们连接到数据库中的同一列:pscUser和curatorUserId。在从数据库获取数据时,这两个字段都由hibernate填写。但是由于insertable=falseand updatable=false在插入过程中仅使用pscUser,而curatorUserId被忽略。回答Alan Hay后,我可以得出结论,我应该始终指定object,否则我的字段在db中为null?不可插入且可更新仅用于排除对db的副作用。因此,您使用null引用持久化对象,并且它保持null(null FK列)…应该如此。当您检索对象时,它检索null(因为数据存储中的FK列为null)。而且?!我在没有指定对象的情况下练习过(:只有它的IDI如果你只有一个id,你没有对象关系,JPA是为对象关系设计的,但是当足够设置curatorUserId时,还有另一个行为。但是pscUser为null。否,因为它被设置为可更新/可插入false。你我在使用ORM,所以要从对象的角度考虑。好的,如果我从对象的角度考虑的话并删除inseartable=false和updateable=false。它会保持它的行为吗?如果我只指定CuratorUserId和pscUser=null,我想它会抱怨重复的列,但请尝试。