如何在表 Spring + Hibernate + Spring Security 中填充外键

Posted

技术标签:

【中文标题】如何在表 Spring + Hibernate + Spring Security 中填充外键【英文标题】:How to populate foreign key in table Spring + Hibernate + Spring Security 【发布时间】:2016-09-28 14:08:37 【问题描述】:

我想举个例子,当用户通过 Spring Security 身份验证然后他填写 adres 表单时,我想自动更新用户表中的外键列“adres_id”。请给我一个提示如何以最流行的方式实现这一点

我怎么会这样

地址表:

用户表:

地址

@Entity
@Table(name="adres")
public class Adres 


    @Id
    @GeneratedValue(strategy = GenerationType.AUTO )
    int id;

    @Column(name="country", nullable=false)
    private String country;
    private String street;
    private String postcode;
    private String telephone;
    private String pesel;


    @OneToOne(mappedBy ="adres")
    private User user;




    public int getId() 
        return id;
    
    public void setId(int id) 
        this.id = id;
    
    public String getPostcode() 
        return postcode;
    
    public void setPostcode(String postcode) 
        this.postcode = postcode;
    

    public String getTelephone() 
        return telephone;
    
    public void setTelephone(String telephone) 
        this.telephone = telephone;
    
    public String getPesel() 
        return pesel;
    
    public void setPesel(String pesel) 
        this.pesel = pesel;
    
    public String getStreet() 
        return postcode;
    
    public void setStreet(String street) 
        this.street = street;
    

    public String getCountry() 
        return country;
    
    public void setCountry(String country) 
        this.country = country;
    



用户

@Entity
@Table(name="users")
public class User 


    @Id
    @GeneratedValue(strategy = GenerationType.AUTO )
    int id;

    @Column(name="username", nullable=false)
    private String username;
    private String password;
    private String email;
    private Boolean enabled;



    @OneToOne(cascade = CascadeType.ALL)
    private Adres adres;


    public Boolean getEnabled() 
        return enabled;
    
    public void setEnabled(Boolean enabled) 
        this.enabled = enabled;
    
    public String getUsername() 
        return username;
    
    public void setUsername(String username) 
        this.username = username;
    
    public String getPassword() 
        return password;
    
    public void setPassword(String password) 
        this.password = password;
    
    public String getEmail() 
        return email;
    
    public void setEmail(String email) 
        this.email = email;
    
    public int getId() 
        return id;
    
    public void setId(int id) 
        this.id = id;
    


AdresDAO

@Repository
@Transactional
public class AdresDAOImpl implements AdresDAO

    @Autowired
    SessionFactory sessionFactory;

    public void addAdres(Adres adres) 
        sessionFactory.getCurrentSession().save(adres);
    

    public List<Adres> listAdres() 

        return sessionFactory.getCurrentSession().createQuery("from Adres order by id").list();
    

    public void removeAdres(int id) 
        Adres adres = (Adres) sessionFactory.getCurrentSession().load(
                Adres.class, id);
        if (null != adres) 
            sessionFactory.getCurrentSession().delete(adres);
        

    
    public Adres getAdres(int id) 

        return (Adres)sessionFactory.getCurrentSession().get(Adres.class, id);
    

  public void editAdres(Adres adres) 

        sessionFactory.getCurrentSession().update(adres);
    




AdresService

@Service
public class AdresServiceImpl implements AdresService

    @Autowired
    AdresDAO adresDAO;



    @Transactional
    public void addAdres(Adres adres) 
        adresDAO.addAdres(adres);

    

    @Transactional
    public void editAdres(Adres adres) 
        adresDAO.editAdres(adres);
    

    @Transactional
    public List<Adres> listAdres() 

        return adresDAO.listAdres();
    

    @Transactional
    public void removeAdres(int id) 
        adresDAO.removeAdres(id);
    

    @Transactional
    public Adres getAdres(int id) 
        return adresDAO.getAdres(id);
    



【问题讨论】:

【参考方案1】:

UserUserAddress 之间的单向关系,如果 Address 对象不应该知道它的所有者(通常它不知道)。如果User 有多个Address(一对多关系),我更喜欢Address 表中的用户ID。

但是对于你的问题,你可以这样设计,

public class User
    ...
    @OneToOne(CascadeType.REMOVE)//this is for to remove address when user is removed
    @JoinColumn(name="HOME_ADDRESS_ID")
    private Address address;
    ...

public class Address 

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO )
    int id;

    @Column(name="country", nullable=false)
    private String country;
    private String street;
    private String postcode;
    private String telephone;
    private String pesel;

    //no user object here

    public int getId() 
        return id;
    
    ...

【讨论】:

我按照你给我的方式设计它,但它仍然不能解决我的问题。当我填充地址对象时,它会填充一个“地址”表,并且我的“用户”表中有一个外键 HOME_ADDRESS_ID,但它没有值。我想在“地址”表和“用户”表中具有相同的“id”值和“HOME_ADDRESS_ID”。如何实现? 所以首先保存您的地址,然后将此地址设置为用户的地址,如 user.setAddress(mySavedNewAddress) 然后您将在用户表中看到地址 ID。 其实在jpa完成它的工作之后它会自动更新你的地址对象的id,但是要确保你新创建的地址在这个操作之后有一个id。 没错!非常感谢,这就是我的意思。一开始我错了,因为我认为使用 JPA 自动升级外键而无需任何设置器 :) 很高兴听到这个消息。

以上是关于如何在表 Spring + Hibernate + Spring Security 中填充外键的主要内容,如果未能解决你的问题,请参考以下文章

hibernate 在表名映射时如何保持大小写区分呢?

org.hibernate.MappingException:无法确定类型:java.util.List,在表:用户,列:[org.hibernate.mapping.Column(事件)]

使用@ElementCollection 时出错:org.hibernate.MappingException:无法确定类型:java.util.Set,在表中:列

将表上的现有条目转换为Hibernate实体对象

如何从 Spring/Hibernate 调用存储的例程/函数?

如何使用 Spring-Security 3 和 Hibernate 4 将 spring security xml 配置 hibernate 转换为 java config