簡體   English   中英

非空屬性引用了持久值的空值或瞬態值

[英]Not-null property references a null or transient value for persisted value

我正在嘗試使用 JPA1 和 Hibernate 實現來持久化兩個不同的實體。 代碼如下所示:

父實體類

@Entity
@Table(name = "parent")
public class Parent implements Serializable {

    {...}
    private Child child;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "child_id", nullable = "false")
    public Child getChild() {
        return child;
    }

    public void setChild(Child child) {
        this.child = child;
}

子實體類

@Entity
@Table(name = "child")
public class Child implements Serializable {

    private Integer id;

    @Id
    @Column(name = "child_id")
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }
}

測試用例

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:META-INF/application.xml")
@Transactional
public class ParentTest extends TestCase {

    @PersistenceContext
    private EntityManager entityManager;

    @Test
    public void testSave() {
        Child child = new Child();
        child.setId(1);

        Parent parent = new Parent();
        parent.setChild(child);

        entityManager.persist(parent.getChild());
        entityManager.persist(parent); // throws the exception
    }
}

application.xml 上的實體管理器和事務

<tx:annotation-driven transaction-manager="transactionManager" /> 

<jee:jndi-lookup id="dataSource" jndi-name="java:/jdbc/myds" expected-type="javax.sql.DataSource" /> 

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="packagesToScan" value="com.mypackage" />
    <property name="dataSource" ref="dataSource" /> 
    <property name="jpaVendorAdapter"› 
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
    </property>
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.dialect>org.hibernate.dialect.Oracle10gDialect</prop>
        </props>
    </property>
</bean> 

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" /> 
</bean>

當嘗試插入父對象時,hibernate 拋出一個 PropertyValueException,說 child 為 null 或瞬態,即使 child 在此操作之前被創建並持久化。 奇怪的是,這只在單元測試中失敗,而在實際應用程序中,使用預先插入的孩子,這正如預期的那樣工作。

PS:我很清楚我可以用級聯持續映射孩子,但這不是這里的想法。 我只想檢查這兩個是否獨立工作。

這里的問題是您使用 set 值持久化父表。 當它持久化時,它需要子表 id,它必須已經被持久化,因為它是一個外鍵,因此它是一個非空屬性引用一個空值。

    @Test
    public void testSave() {
        Child child = new Child();
        child.setId(1);
        entityManager.persist(child); 

        Parent parent = new Parent();
        parent.setChild(child);

        entityManager.persist(parent); 
    }

嘗試先保存孩子,然后再保存父母。否則更改映射

您在 Parent 中使用 @ManyToOne 的第一件事告訴我,一個 Child 對象有多個父對象,我想情況並非如此。

根據您的類結構,我可以理解您在父實體和子實體之間有 OneToOne 映射。

關於例外,您是否有理由不使用父級和子級之間的級聯來自動處理保存、更新和刪除的映射? 如果您還沒有考慮過它,那么您可以按照此處指定的方式設置以下配置來嘗試一下: 示例父/子 - Hibernate

cascade = {CascadeType.ALL}

盡管我建議將 Child 和 Parent 之間的映射從 ManyToOne 更改為 OneToOne。

請告訴我。

除了有一個 FK 到子問題的父級之外,持久順序是導致您出現問題的原因。

您的問題與沖洗有關 僅僅因為您指示 Hibernate 持久化一個對象,並不意味着它會自動滿足您的請求。 持久請求進入操作隊列,僅在刷新時實現。 所以你的第二個堅持只是找到沒有實際“持久化”孩子的父實體。

您可以簡單地修復您的代碼,如下所示:

    Child child = new Child();
    child.setId(1);

    entityManager.persist(parent.getChild());
    entityManager.flush();

    Parent parent = new Parent();
    parent.setChild(child);
    entityManager.persist(parent);
    entityManager.flush;

嘗試這個:

@ManyToOne(fetch = FetchType.LAZY,optional=false)
@JoinColun(name = "child_id", nullable = "false")
public Child getChild() {
    return child;
}

某些字段設置為not-null="true"您必須在保存到 db 之前為其提供值。 對於父表和子表中的所有字段,將所有非空字段設置為適當的值

嘗試為public Child getChild()提供@ManyToOne(fetch = FetchType.LAZY,cascade=PERSIST, mappedBy="parent") public Child getChild()並僅保留父對象。兩者都將被保留。

我有一個類似的問題,我在測試中收到一條錯誤消息,指出“not-null 屬性引用了一個空值或瞬態值”,但在正常運行應用程序時卻沒有。

結果我只需要在hibernate.properties文件中添加一行:

hibernate.check_nullability=false

出於某種原因,此選項在運行應用程序時默認設置為 false,但在測試時設置為 true。 將它添加到hibernate.properties不會影響正在運行的應用程序,但修復了測試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM