hibernate - 如何一次性保留所有实体和子实体

时间:2014-09-26 16:35:55

标签: java spring hibernate jpa

需要一些Hibernate问题的帮助。

1)想要一次运行create()方法,从一个对象中持久保存所有实体和子实体。有可能吗?

2)连接表有问题。没有什么是持久的。我尝试将@ManyToMany映射放在PersonAddress类中的Set集合中。从未使它工作并填充数据库中的PERSON_ADDRESS表。

我尝试从测试用例类中运行两种测试方法。他们都在git。方法是testJoinTable()testLoadEverything()。请看一下。 Hibernate映射在模型包中的类中。

Address.java

@Entity
@Table(name = "ADDRESS")
public class Address implements Serializable {

    @ManyToOne(targetEntity = Country.class)
    @JoinColumn(name = "COUNTRY_ID", referencedColumnName = "COUNTRY_ID", insertable = true, nullable = true, unique = false, updatable = true)
    private Country country;

    @ManyToMany( mappedBy = "address" )
    private Set<Person> persons = new HashSet<Person>();

    @Column(name = "STREET", length = 100)
    private String street;

    @Column(name = "POST_CODE", length = 50)
    private String postCode;

    @Column(name = "ADDRESS_TYPE", length = 50)
    private String addressType;

    @Column(name = "ADDRESS_ID", nullable = false, precision = 20)
    @Id
    @SequenceGenerator(name = "AddressSeq", sequenceName = "ADDRESS_SEQ", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "AddressSeq")
    private Long addressId;

    @Column(name = "CITY", length = 100)
    private String city;

    @Column(name = "CREATED_ON", nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date createdOn;

    @Column(name = "MODIFIED_ON")
    @Temporal(TemporalType.TIMESTAMP)
    private Date modifiedOn;

    @Column(name = "DISTRICT_NAME", length = 100)
    private String districtName;

    @OneToMany ( fetch = FetchType.LAZY, targetEntity = SomeId.class, mappedBy = "address" )
    @Cascade({CascadeType.SAVE_UPDATE, CascadeType.ALL})
    private Set<SomeId> someIds;

}

Person.java

@Entity
@Table(name = "PERSON")
public class Person implements Serializable {

    @Column(name = "PERSON_ID", nullable = false, precision = 20)
    @Id
    private Long personId;

    @ManyToMany
    @JoinTable(name="PERSON_ADDRESS", 
                joinColumns={@JoinColumn(name="PERSON_ID")}, 
                inverseJoinColumns={@JoinColumn(name="ADDRESS_ID")})
    private Set<Address> address = new HashSet<Address>();

    @Column(name = "CREATED_ON", nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date createdOn;

    @Column(name = "MODIFIED_ON")
    @Temporal(TemporalType.TIMESTAMP)
    private Date modifiedOn;
}

Country.java

@Entity
@Table(name = "COUNTRY")
@NamedQuery(name = "findCountryByCode", query = "from Country where code like :code")
public class Country implements Serializable {

    @Column(name = "COUNTRY_ID", nullable = false, precision = 20)
    @Id
    @SequenceGenerator(name = "CountrySeq", sequenceName = "COUNTRY_SEQ", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "CountrySeq")
    private Long countryId;

    @OneToMany(targetEntity = Birth.class, mappedBy = "country")
    private Collection<Birth> birthCollection;

    @OneToMany(targetEntity = Address.class, mappedBy = "country")
    private Collection<Address> addressCollection;

    @Column(name = "CODE", nullable = false, length = 2)
    private String code;

    @Column(name = "CREATED_ON", nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date createdOn;

    @Column(name = "MODIFIED_ON")
    @Temporal(TemporalType.TIMESTAMP)
    private Date modifiedOn;
}

SomeId.java

@Entity
@Table( name = "SOME_ID" )
public class SomeId {

    @Column( name = "SOME_ID_ID", unique = true, nullable = false, precision = 20, scale = 0 )
    @Id
    @SequenceGenerator( name = "SomeIdSeq", sequenceName = "SOME_ID_ID_SEQ", allocationSize = 1 )
    @GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "SomeIdSeq" )
    private Long someIdId;

    @ManyToOne( optional = false, targetEntity = Address.class, fetch = FetchType.EAGER)
    @JoinColumn( name = "ADDRESS_ID", referencedColumnName = "ADDRESS_ID", insertable = true, nullable = true, unique = false, updatable = true )
    private Address address;

    @Column( name = "CREATED_ON", nullable = false )
    @Temporal( TemporalType.TIMESTAMP )
    private Date createdOn;

    @Column( name = "MODIFIED_ON" )
    @Temporal( TemporalType.TIMESTAMP )
    private Date modifiedOn;

    @Column( name = "SOME_ID", nullable = false, length = 100 )
    private String someId;
}

为了更容易理解我想要完成的任务,我将在此处粘贴我的测试方法:

@Test
public void testJoinTable() {
    addressDao.create( address1 );
    addressDao.create( address2 );
    Address address = addressDao.get( address2.getAddressId() );
    assertTrue("address2 don't have 3 persons as expected", address.getPersons().size() == 3);
    long numberOfRecordsInJoinTable = personAddressDao.count();
    assertTrue( "join table PERSON_ADDRESS is not used by Hibernate", numberOfRecordsInJoinTable > 0 );
}

@Test
public void testLoadEverything() {
    address1.setSomeIds( new HashSet<SomeId>() );
    address1.getSomeIds().add( someId1 );
    address1.getSomeIds().add( someId2 );
    addressDao.create( address1 );
    long numberOfRecordsInSomeIdTable = someIdDao.count();
    assertTrue("someIds are not persisted", numberOfRecordsInSomeIdTable > 0);
}

1 个答案:

答案 0 :(得分:2)

您似乎需要在Person&gt;上指定manytomany上的级联选项。地址:

http://en.wikibooks.org/wiki/Java_Persistence/Relationships#Cascading