UnresolvedEntityInsertActions

UnresolvedEntityInsertActions

本文介绍了与JPA注解的双向@OneToMany关系似乎不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是参考这个。


This is in reference to this answer.

Entities-

// Many to One

@Entity
@Table
public class Address {

    @Id
    @GeneratedValue
    @Column
    private int addressIdentity;

    @Column
    private int houseNo;

    @Column
    private char streetNo;

    @Column
    private int pincode;

    @Column
    private String city;

    @Column
    private String state;

    @Column
    private String country;

    @ManyToOne
       @JoinTable(name="PersonAddress",
            joinColumns=@JoinColumn(name="addressId", insertable = false, updatable = false),
            inverseJoinColumns=@JoinColumn(name="personId", insertable = false, updatable = false)
       )
    private Person person;
    // getters and setters


One to Many

@Entity
@Table
public class Person {

    @Id
    @GeneratedValue
    @Column
    private int personId;

    @Column
    private String name;

    @Column
    private String designation;

    @OneToMany
    @JoinTable(name = "PersonAddress",
                            joinColumns = @JoinColumn(name = "personId"),
                                inverseJoinColumns = @JoinColumn(name = "addressId"))
    private Set<Address> addSet = new HashSet<Address>();
    // getters and setters


Hibernate configuration file-

<hibernate-configuration>
    <session-factory name="">
        <property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
        <property name="hibernate.connection.password">hello</property>
        <property name="hibernate.connection.url">jdbc:postgresql://localhost:5432/xyz</property>
        <property name="hibernate.connection.username">postgres</property>
        <property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
        <property name="show_sql">true</property>
        <property name="hbm2ddl.auto">create</property>
        <mapping class="ManyToOne_OneToManyMappingWithJoinTable.Person" />
        <mapping class="ManyToOne_OneToManyMappingWithJoinTable.Address" />
    </session-factory>
</hibernate-configuration>


the persistence logic-

        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
        Session session = sessionFactory.openSession();
        session.beginTransaction();

        Person person1 = new Person();
        person1.setName("Shahnaz Parveen");
        person1.setDesignation("HouseWife");

        Address address1 = new Address();
        address1.setHouseNo(18);
        address1.setStreetNo('E');
        address1.setPincode(250002);
        address1.setCity("Meerut");
        address1.setState("UP");
        address1.setCountry("INDIA");
        address1.setPerson(person1);

        Address address2 = new Address();
        address2.setHouseNo(84);
        address2.setStreetNo('1');
        address2.setPincode(250002);
        address2.setCity("Meerut");
        address2.setState("UP");
        address2.setCountry("INDIA");
        address1.setPerson(person1);

        person1.getAddSet().add(address1);
        person1.getAddSet().add(address2);

        session.save(address1);
        session.save(address2);
        session.save(person1);

        session.getTransaction().commit();
        session.close();


I am getting -

Jan 07, 2017 9:47:35 PM org.hibernate.action.internal.UnresolvedEntityInsertActions logCannotResolveNonNullableTransientDependencies
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: ([ManyToOne_OneToManyMappingWithJoinTable.Person#0])
    Dependent entities: ([[ManyToOne_OneToManyMappingWithJoinTable.Address#1]])
    Non-nullable association(s): ([ManyToOne_OneToManyMappingWithJoinTable.Address.person])
Exception in thread "main" org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved beforeQuery current operation : ManyToOne_OneToManyMappingWithJoinTable.Address.person -> ManyToOne_OneToManyMappingWithJoinTable.Person
    at org.hibernate.action.internal.UnresolvedEntityInsertActions.checkNoUnresolvedActionsAfterOperation(UnresolvedEntityInsertActions.java:122)
    at org.hibernate.engine.spi.ActionQueue.checkNoUnresolvedActionsAfterOperation(ActionQueue.java:418)
    at org.hibernate.internal.SessionImpl.checkNoUnresolvedActionsAfterOperation(SessionImpl.java:621)
    at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:684)
    at org.hibernate.internal.SessionImpl.save(SessionImpl.java:674)
    at org.hibernate.internal.SessionImpl.save(SessionImpl.java:669)
    at ManyToOne_OneToManyMappingWithJoinTable.ManyToOne_OneToManyMappingWithJoinTableImpl.main(ManyToOne_OneToManyMappingWithJoinTableImpl.java:40)

It works perfect with hbms.

Please suggest.


Thanks Vlad and Neil, it works but there is a problem described below-

This is the structure which gets created with HBMs. Hence the same must be with Annotations.

CREATE TABLE person_address
(
  addressid integer NOT NULL,
  personid integer NOT NULL,
  CONSTRAINT person_address_pkey PRIMARY KEY (addressid , personid ),
  CONSTRAINT fkkpp6mysmnyiywx3q33yxr1gbe FOREIGN KEY (personid )
      REFERENCES person (person_id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT fkrpk0jx2y558su288tx9kd5cs6 FOREIGN KEY (addressid )
      REFERENCES address (address_id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)

the moment I do -

@OneToMany(cascade = CascadeType.ALL, mappedBy = "person")
private Set<Address> addSet = new HashSet<Address>();

the join table structure is-

CREATE TABLE personaddress
(
  personid integer,
  addressid integer NOT NULL,
  CONSTRAINT personaddress_pkey PRIMARY KEY (addressid),
  CONSTRAINT fkfd5pm843bldj10y5kxwo37xge FOREIGN KEY (addressid)
      REFERENCES address (addressidentity) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT fkjuwlthwsi53bpf902nnl6snxh FOREIGN KEY (personid)
      REFERENCES person (personid) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)

You see that the primary key is NOT a combination of addressid and personid as in HBMs. Please suggest.

解决方案

You need to add a cascade the one-to-many side:

@OneToMany(cascade = CascadeType.ALL)

Check out this article for more details.

Then, change the @ManyToOne side to:

@ManyToOne
@JoinTable(name="PersonAddress",
    joinColumns=@JoinColumn(name="addressId"),
    inverseJoinColumns=@JoinColumn(name="personId")
)
private Person person;

and the @OneToMany side to:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "person")
private Set<Address> addSet = new HashSet<Address>();

Update

To address the composite-key requirement as indicated by the question update, try mapping the join table (e.g. personaddress) as an entity, and use composite keys as explained in this article.

这篇关于与JPA注解的双向@OneToMany关系似乎不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 07:45