not-null属性以主键作为连接列一对一引用null或瞬时值

时间:2020-08-03 07:29:44

标签: hibernate jpa

有人可以在这里帮助我,为什么我遇到例外。我检查了各种类似的链接,但没有人匹配此用例。 我正在尝试通过主键作为用户表中的连接列在用户表和地址表之间创建关系。

休眠版本-5.2.18

Hibernate: create table User (userId numeric(19,0) not null, primary key (userId))
Hibernate: select next_val as id_val from hibernate_sequence with (updlock, rowlock)
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.PropertyValueException: not-null property references a null or transient value : com.vikas.projects.hibernate.tests.oneTone.User.shippingAddress
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:149)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:157)

Users.java


import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;

@Entity
@Table(name="USERS")
public class User {
    
    @Id
    private Long id;
    
    @Column (nullable = false)
    private String firstName;
    
    @Column (nullable = false)
    private String lastName;
    
    @OneToOne(
            fetch=FetchType.LAZY,
            optional=false
            )
    @PrimaryKeyJoinColumn
    private Address shippingAddress;
    
    public User() {
        
    }
    
    public User(Long id, String fName, String lName) {
        this.id = id;
        this.firstName = fName;
        this.lastName = lName;
    }

}

Address.java


import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Address {
    
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;
    @Column (nullable=false)
    private String city;
    @Column (nullable = false)
    private String street;
    
    public Address() {
        
    }
    
    public Address (String city, String street) {
        this.city = city;
        this.street = street;
    }
    
    public Long getId() {
        return id;
    }
    
    public void setCity(String city) {
        this.city = city;
    }
    
    public void setStreet(String street) {
        this.street=street;
    }

}

ApplicationTest.java


import org.hibernate.Session;
import org.hibernate.Transaction;

import com.vikas.projects.hibernate.tests.DbOperations;

public class ApplicationTest {
    
    public static void main( String[] args) {
        Address shippingAddress = new Address("CityNameLiteral", "StreetNameLiteral");
        Session session = DbOperations.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        session.persist(shippingAddress);
        Long shippingAddressId = shippingAddress.getId();
        User userObj = new User(shippingAddressId, "firstNameLiteral", "lastNameLiteral");
        session.persist(userObj);
        tx.commit();
        session.close();
        
    }

}

谢谢

1 个答案:

答案 0 :(得分:0)

您的用户构造函数如下:

public User(Long id, String fName, String lName) {
    this.id = id;
    this.firstName = fName;
    this.lastName = lName;
}

您正在像这样使用它:

User userObj = new User(shippingAddressId, "firstNameLiteral", "lastNameLiteral");

这意味着您将用户对象ID设置为送货地址ID,但实际上并未将用户中的送货地址对象设置为任何对象。

以下步骤可以解决您的问题:

public class User {
    // Add @GeneratedValue to your User#id (I think you don't need to set the strategy 
    // here, but not 100% sure)
    @Id
    @GeneratedValue
    private Long id;

    // ...
}
// Change User constructor like this
public User(Address shippingAddress, String fName, String lName) {
    this.shippingAddress = shippingAddress;
    this.firstName = fName;
    this.lastName = lName;
}
public static void main( String[] args) {
    Address shippingAddress = new Address("CityNameLiteral", "StreetNameLiteral");
    Session session = DbOperations.getSessionFactory().openSession();
    Transaction tx = session.beginTransaction();
    session.persist(shippingAddress);
    // Use the Adress object now
    User userObj = new User(shippingAdress, "firstNameLiteral", "lastNameLiteral");
    session.persist(userObj);
    tx.commit();
    session.close();
}

如果不能确定,尽管它提供了2个表的解决方案,但我还是建议您遵循此示例:https://vladmihalcea.com/the-best-way-to-map-a-onetoone-relationship-with-jpa-and-hibernate/