Hibernate Delete引用:TransientPropertyValueException:非null属性引用瞬态值

时间:2015-04-27 06:49:27

标签: java hibernate hibernate-mapping


我正在使用Hibernate 4.3.8.Final,我需要为帖子建模 为了满足我的要求,我必须定义2个表:

  • USERS:其中包含有关用户的信息(对于此示例,id和电子邮件就足够了)
  • POST:将包含帖子的信息(撰写帖子和评论的用户)

要使用Hibernate,我通过XML定义了映射。

Hibernate配置文件

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://192.168.2.137/Test</property>
        <property name="hibernate.connection.username">user</property>
        <property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
        <property name="hibernate.c3p0.acquire_increment">1</property>
        <property name="hibernate.c3p0.idle_test_period">100</property>
        <property name="hibernate.c3p0.min_size">10</property>
        <property name="hibernate.c3p0.max_size">10</property>
        <property name="hibernate.c3p0.max_statements">10</property>
        <!-- Show the SQL statements in the log -->
        <property name="query.substitutions">true</property>
        <property name="format_sql">true</property>
        <property name="use_sql_comments">true</property>
        <!-- List of XML mapping files -->
        <mapping class="example.data.model.User" resource="User.hbm.xml"/>
        <mapping class="example.data.model.Post" resource="Post.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

用户映射

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="example.data.model.User" table="USERS">
        <id name="id" type="int" column="id">
            <generator class="native"/>
        </id>
        <property name="email" column="email" type="string"/>
        <set name="posts" inverse="true" fetch="select" cascade="all">
            <key column="user_id" not-null="true"/>
            <many-to-many column="id" class="example.data.model.Post"/>
        </set>
    </class>
</hibernate-mapping>

发布映射

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="example.data.model.Post" table="POST">
        <id name="id" type="int" column="id">
            <generator class="native"/>
        </id>
        <many-to-one name="user" column="user_id" unique="true" class="example.data.model.User" not-null="true" />
        <property name="comment" column="comment" type="string"/>
    </class>
</hibernate-mapping>

测试代码

package example;

import example.data.model.Post;
import example.data.model.User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;

import java.util.Random;

public class Main {
    public static void main(String args[]) {
        SessionFactory sessionFactory;
        Session session;
        try {
            // Initialize factory using contents of hibernate.cfg.xml
            Configuration configuration = new Configuration();
            configuration.configure();
            StandardServiceRegistryBuilder ssrb = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
            sessionFactory = configuration.buildSessionFactory(ssrb.build());
            session = sessionFactory.openSession();
        } catch (Throwable ex) {
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }

        User user = new User().setEmail("email" + new Random().nextInt(1000));
        Post post = new Post().setUser(user).setComment("comment");

        Transaction transaction = session.beginTransaction();
        session.save(post);
        transaction.commit();
        System.out.println(user.toString());

        Post retrievedPost = (Post) session.get(Post.class, post.getId());
        transaction = session.beginTransaction();
        session.delete(retrievedPost);
        transaction.commit();
    }
}

问题 当我尝试删除(session.delete)帖子时,我获得了以下异常。

 Exception in thread "main" org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation : example.data.model.Post.user -> example.data.model.User
 at org.hibernate.action.internal.UnresolvedEntityInsertActions.checkNoUnresolvedActionsAfterOperation(UnresolvedEntityInsertActions.java:137)
 at org.hibernate.engine.spi.ActionQueue.checkNoUnresolvedActionsAfterOperation(ActionQueue.java:320)
 at org.hibernate.internal.SessionImpl.checkNoUnresolvedActionsAfterOperation(SessionImpl.java:658)
 at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:717)
 at org.hibernate.internal.SessionImpl.save(SessionImpl.java:707)
 at org.hibernate.internal.SessionImpl.save(SessionImpl.java:702)
 at example.Main.main(Main.java:33)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:606)
 at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

整个日志输出

[DEBUG] Adding type registration boolean -> org.hibernate.type.BooleanType@63435263
[DEBUG] Adding type registration boolean -> org.hibernate.type.BooleanType@63435263
[DEBUG] Adding type registration java.lang.Boolean -> org.hibernate.type.BooleanType@63435263
[DEBUG] Adding type registration numeric_boolean -> org.hibernate.type.NumericBooleanType@430ef1aa
[DEBUG] Adding type registration true_false -> org.hibernate.type.TrueFalseType@23365dcc
[DEBUG] Adding type registration yes_no -> org.hibernate.type.YesNoType@7c8a5ff0
[DEBUG] Adding type registration byte -> org.hibernate.type.ByteType@7ff26e9d
[DEBUG] Adding type registration byte -> org.hibernate.type.ByteType@7ff26e9d
[DEBUG] Adding type registration java.lang.Byte -> org.hibernate.type.ByteType@7ff26e9d
[DEBUG] Adding type registration character -> org.hibernate.type.CharacterType@1fa76740
[DEBUG] Adding type registration char -> org.hibernate.type.CharacterType@1fa76740
[DEBUG] Adding type registration java.lang.Character -> org.hibernate.type.CharacterType@1fa76740
[DEBUG] Adding type registration short -> org.hibernate.type.ShortType@4e181a7a
[DEBUG] Adding type registration short -> org.hibernate.type.ShortType@4e181a7a
[DEBUG] Adding type registration java.lang.Short -> org.hibernate.type.ShortType@4e181a7a
[DEBUG] Adding type registration integer -> org.hibernate.type.IntegerType@2ed053a
[DEBUG] Adding type registration int -> org.hibernate.type.IntegerType@2ed053a
[DEBUG] Adding type registration java.lang.Integer -> org.hibernate.type.IntegerType@2ed053a
[DEBUG] Adding type registration long -> org.hibernate.type.LongType@7d6545e
[DEBUG] Adding type registration long -> org.hibernate.type.LongType@7d6545e
[DEBUG] Adding type registration java.lang.Long -> org.hibernate.type.LongType@7d6545e
[DEBUG] Adding type registration float -> org.hibernate.type.FloatType@7b17cda3
[DEBUG] Adding type registration float -> org.hibernate.type.FloatType@7b17cda3
[DEBUG] Adding type registration java.lang.Float -> org.hibernate.type.FloatType@7b17cda3
[DEBUG] Adding type registration double -> org.hibernate.type.DoubleType@462938d8
[DEBUG] Adding type registration double -> org.hibernate.type.DoubleType@462938d8
[DEBUG] Adding type registration java.lang.Double -> org.hibernate.type.DoubleType@462938d8
[DEBUG] Adding type registration big_decimal -> org.hibernate.type.BigDecimalType@67333875
[DEBUG] Adding type registration java.math.BigDecimal -> org.hibernate.type.BigDecimalType@67333875
[DEBUG] Adding type registration big_integer -> org.hibernate.type.BigIntegerType@46d0cc3a
[DEBUG] Adding type registration java.math.BigInteger -> org.hibernate.type.BigIntegerType@46d0cc3a
[DEBUG] Adding type registration string -> org.hibernate.type.StringType@f970646
[DEBUG] Adding type registration java.lang.String -> org.hibernate.type.StringType@f970646
[DEBUG] Adding type registration nstring -> org.hibernate.type.StringNVarcharType@756ac176
[DEBUG] Adding type registration ncharacter -> org.hibernate.type.CharacterNCharType@3379bd14
[DEBUG] Adding type registration url -> org.hibernate.type.UrlType@3b870cfc
[DEBUG] Adding type registration java.net.URL -> org.hibernate.type.UrlType@3b870cfc
[DEBUG] Adding type registration date -> org.hibernate.type.DateType@3c4e80d3
[DEBUG] Adding type registration java.sql.Date -> org.hibernate.type.DateType@3c4e80d3
[DEBUG] Adding type registration time -> org.hibernate.type.TimeType@3d9061ec
[DEBUG] Adding type registration java.sql.Time -> org.hibernate.type.TimeType@3d9061ec
[DEBUG] Adding type registration timestamp -> org.hibernate.type.TimestampType@5152441a
[DEBUG] Adding type registration java.sql.Timestamp -> org.hibernate.type.TimestampType@5152441a
[DEBUG] Adding type registration java.util.Date -> org.hibernate.type.TimestampType@5152441a
[DEBUG] Adding type registration dbtimestamp -> org.hibernate.type.DbTimestampType@5689a400
[DEBUG] Adding type registration calendar -> org.hibernate.type.CalendarType@2e746d6d
[DEBUG] Adding type registration java.util.Calendar -> org.hibernate.type.CalendarType@2e746d6d
[DEBUG] Adding type registration java.util.GregorianCalendar -> org.hibernate.type.CalendarType@2e746d6d
[DEBUG] Adding type registration calendar_date -> org.hibernate.type.CalendarDateType@399a8684
[DEBUG] Adding type registration locale -> org.hibernate.type.LocaleType@7df4591e
[DEBUG] Adding type registration java.util.Locale -> org.hibernate.type.LocaleType@7df4591e
[DEBUG] Adding type registration currency -> org.hibernate.type.CurrencyType@225ac214
[DEBUG] Adding type registration java.util.Currency -> org.hibernate.type.CurrencyType@225ac214
[DEBUG] Adding type registration timezone -> org.hibernate.type.TimeZoneType@29d54d9a
[DEBUG] Adding type registration java.util.TimeZone -> org.hibernate.type.TimeZoneType@29d54d9a
[DEBUG] Adding type registration class -> org.hibernate.type.ClassType@5214cda3
[DEBUG] Adding type registration java.lang.Class -> org.hibernate.type.ClassType@5214cda3
[DEBUG] Adding type registration uuid-binary -> org.hibernate.type.UUIDBinaryType@701f42b
[DEBUG] Adding type registration java.util.UUID -> org.hibernate.type.UUIDBinaryType@701f42b
[DEBUG] Adding type registration uuid-char -> org.hibernate.type.UUIDCharType@4641439f
[DEBUG] Adding type registration pg-uuid -> org.hibernate.type.PostgresUUIDType@23964a8d
[DEBUG] Adding type registration binary -> org.hibernate.type.BinaryType@2c888fc9
[DEBUG] Adding type registration byte[] -> org.hibernate.type.BinaryType@2c888fc9
[DEBUG] Adding type registration [B -> org.hibernate.type.BinaryType@2c888fc9
[DEBUG] Adding type registration wrapper-binary -> org.hibernate.type.WrapperBinaryType@41f4fa12
[DEBUG] Adding type registration Byte[] -> org.hibernate.type.WrapperBinaryType@41f4fa12
[DEBUG] Adding type registration [Ljava.lang.Byte; -> org.hibernate.type.WrapperBinaryType@41f4fa12
[DEBUG] Adding type registration image -> org.hibernate.type.ImageType@26c69727
[DEBUG] Adding type registration characters -> org.hibernate.type.CharArrayType@8cf76c0
[DEBUG] Adding type registration char[] -> org.hibernate.type.CharArrayType@8cf76c0
[DEBUG] Adding type registration [C -> org.hibernate.type.CharArrayType@8cf76c0
[DEBUG] Adding type registration wrapper-characters -> org.hibernate.type.CharacterArrayType@3e019dc4
[DEBUG] Adding type registration [Ljava.lang.Character; -> org.hibernate.type.CharacterArrayType@3e019dc4
[DEBUG] Adding type registration Character[] -> org.hibernate.type.CharacterArrayType@3e019dc4
[DEBUG] Adding type registration text -> org.hibernate.type.TextType@147878c8
[DEBUG] Adding type registration ntext -> org.hibernate.type.NTextType@7561af7c
[DEBUG] Adding type registration blob -> org.hibernate.type.BlobType@28d3ee1b
[DEBUG] Adding type registration java.sql.Blob -> org.hibernate.type.BlobType@28d3ee1b
[DEBUG] Adding type registration materialized_blob -> org.hibernate.type.MaterializedBlobType@fbfa8de
[DEBUG] Adding type registration clob -> org.hibernate.type.ClobType@70af26de
[DEBUG] Adding type registration java.sql.Clob -> org.hibernate.type.ClobType@70af26de
[DEBUG] Adding type registration nclob -> org.hibernate.type.NClobType@1df07586
[DEBUG] Adding type registration java.sql.NClob -> org.hibernate.type.NClobType@1df07586
[DEBUG] Adding type registration materialized_clob -> org.hibernate.type.MaterializedClobType@3eb7d774
[DEBUG] Adding type registration materialized_nclob -> org.hibernate.type.MaterializedNClobType@72fd5ba8
[DEBUG] Adding type registration serializable -> org.hibernate.type.SerializableType@618e8b78
[DEBUG] Adding type registration object -> org.hibernate.type.ObjectType@321b1228
[DEBUG] Adding type registration java.lang.Object -> org.hibernate.type.ObjectType@321b1228
[DEBUG] Adding type registration imm_date -> org.hibernate.type.AdaptedImmutableType@66e27547
[DEBUG] Adding type registration imm_time -> org.hibernate.type.AdaptedImmutableType@1d81bd16
[DEBUG] Adding type registration imm_timestamp -> org.hibernate.type.AdaptedImmutableType@30a4fe7c
[DEBUG] Adding type registration imm_dbtimestamp -> org.hibernate.type.AdaptedImmutableType@203f97d7
[DEBUG] Adding type registration imm_calendar -> org.hibernate.type.AdaptedImmutableType@2f09b4cb
[DEBUG] Adding type registration imm_calendar_date -> org.hibernate.type.AdaptedImmutableType@263c938d
[DEBUG] Adding type registration imm_binary -> org.hibernate.type.AdaptedImmutableType@52fb2197
[DEBUG] Adding type registration imm_serializable -> org.hibernate.type.AdaptedImmutableType@655a6b10
[INFO] HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
[INFO] HHH000412: Hibernate Core {4.3.8.Final}
[INFO] HHH000206: hibernate.properties not found
[INFO] HHH000021: Bytecode provider name : javassist
[INFO] HHH000043: Configuring from resource: /hibernate.cfg.xml
[INFO] HHH000040: Configuration resource: /hibernate.cfg.xml
[INFO] HHH000221: Reading mappings from resource: User.hbm.xml
[INFO] HHH000221: Reading mappings from resource: Post.hbm.xml
[INFO] HHH000041: Configured SessionFactory: null
[INFO] HHH000130: Instantiating explicit connection provider: org.hibernate.connection.C3P0ConnectionProvider
[INFO] HHH010002: C3P0 using driver: com.mysql.jdbc.Driver at URL: jdbc:mysql://192.168.2.137/Test
[INFO] HHH000046: Connection properties: {user=user}
[INFO] HHH000006: Autocommit mode: false
[INFO] MLog clients using log4j logging.
[INFO] Initializing c3p0-0.9.2.1 [built 20-March-2013 10:47:27 +0000; debug? true; trace: 10]
[INFO] Initializing c3p0 pool... com.mchange.v2.c3p0.PoolBackedDataSource@eaff1d5b [ connectionPoolDataSource -> com.mchange.v2.c3p0.WrapperConnectionPoolDataSource@ec262c8b [ acquireIncrement -> 1, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, debugUnreturnedConnectionStackTraces -> false, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 1hge1a9981x8td171mkczwg|6bbe5a32, idleConnectionTestPeriod -> 100, initialPoolSize -> 10, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 10, maxStatements -> 10, maxStatementsPerConnection -> 0, minPoolSize -> 10, nestedDataSource -> com.mchange.v2.c3p0.DriverManagerDataSource@5cdab4d2 [ description -> null, driverClass -> null, factoryClassLocation -> null, identityToken -> 1hge1a9981x8td171mkczwg|3711e4cc, jdbcUrl -> jdbc:mysql://192.168.2.137/Test, properties -> {user=******} ], preferredTestQuery -> null, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false; userOverrides: {} ], dataSourceName -> null, factoryClassLocation -> null, identityToken -> 1hge1a9981x8td171mkczwg|268bb0b0, numHelperThreads -> 3 ]
[INFO] HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
[INFO] HHH000424: Disabling contextual LOB creation as createClob() method threw error : java.lang.reflect.InvocationTargetException
[INFO] HHH000399: Using default transaction strategy (direct JDBC transactions)
[INFO] HHH000397: Using ASTQueryTranslatorFactory
[TRACE] Scoping types to session factory org.hibernate.internal.SessionFactoryImpl@68cf5e45
Exception in thread "main" org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation : example.data.model.Post.user -> example.data.model.User
    at org.hibernate.action.internal.UnresolvedEntityInsertActions.checkNoUnresolvedActionsAfterOperation(UnresolvedEntityInsertActions.java:137)
    at org.hibernate.engine.spi.ActionQueue.checkNoUnresolvedActionsAfterOperation(ActionQueue.java:320)
    at org.hibernate.internal.SessionImpl.checkNoUnresolvedActionsAfterOperation(SessionImpl.java:658)
    at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:717)
    at org.hibernate.internal.SessionImpl.save(SessionImpl.java:707)
    at org.hibernate.internal.SessionImpl.save(SessionImpl.java:702)
    at example.Main.main(Main.java:33)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
[WARN] HHH000437: Attempting to save one or more entities that have a non-nullable association with an unsaved transient entity. The unsaved transient entity must be saved in an operation prior to saving these dependent entities.
    Unsaved transient entity: ([example.data.model.User#<null>])
    Dependent entities: ([[example.data.model.Post#<null>]])
    Non-nullable association(s): ([example.data.model.Post.user])

Process finished with exit code 1

整个项目可在https://www.dropbox.com/s/v0fe3djyro2q7ry/Example.zip?dl=0

上找到

2 个答案:

答案 0 :(得分:0)

例外说:

  

线程“main”中的异常   org.hibernate.TransientPropertyValueException:非null属性   引用瞬态值 - 必须先保存瞬态实例   当前操作:example.data.model.Post.user - &gt;   example.data.model.User

它发生在33计划的第Main.java行。

at org.hibernate.internal.SessionImpl.save(SessionImpl.java:702)
at example.Main.main(Main.java:33)

因此,当您尝试保存Post实体时出现问题:

session.save(post);

要解决此问题,您必须在保存User实体之前保存Post实体,如下所示:

    Transaction transaction = session.beginTransaction();
    session.save(user);
    session.save(post);
    transaction.commit();

现在进入delete操作,您必须打开一个新会话以获取Post的对象,然后将其删除,如下所示:

    Transaction transaction = session.beginTransaction();
    session.save(user);
    session.save(post);
    transaction.commit();
    session.close(); // Closing the session here
    System.out.println(user.toString());

    session = sessionFactory.openSession(); // Opening a new session
    transaction = session.beginTransaction();
    Post retrievedPost = (Post) session.get(Post.class, post.getId());
    session.delete(retrievedPost);
    transaction.commit();

答案 1 :(得分:0)

我认为你需要先保存用户.. 那么你可以保存帖子。也许你需要检查你的实体映射