2

我不喜欢发布一个被问了 1000 次的问题(如果不是更多),就像你不喜欢阅读这些重复的问题一样……但我现在很难过。我不明白为什么所有这些帖子中的典型解决方案,即 using 'CascadeType.ALL',在这里不起作用——

复合键

@Entity
@org.hibernate.annotations.Entity(selectBeforeUpdate = true, dynamicUpdate = true, dynamicInsert = true)
@Table(name = "A")
@SequenceGenerator(initialValue = 1, name = "a_id_gen", sequenceName = "a_id_seq")
public class ABean {

  @Id
  @Column(name = "ID")
  @Generated(GenerationTime.INSERT)
  @GeneratedValue(strategy = GenerationType.AUTO, generator = "a_id_gen")
  private long id;

  @Column(name = "NAME")
  private String name;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }
}

-

@Embeddable
public class MainPrimaryKey implements Serializable {

  @JoinColumn(name = "A_ID", referencedColumnName = "ID", insertable = true, updatable = true, nullable = false)
  @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
  private ABean a;

  public ABean getABean() {
    return a;
  }

  public void setABean(ABean a) {
    this.a = a;
  }
}

实体

@Entity
@org.hibernate.annotations.Entity(selectBeforeUpdate = true, dynamicUpdate = true, dynamicInsert = true)
@Table(name = "Main", schema = "public")
public class Main implements Serializable {

  private static final long serialVersionUID = 3028687015173402553L;

  @Column(name = "A_ID", insertable = false, updatable = false)
  private Integer aId;

  @EmbeddedId
  private MainPrimaryKey pk;

  public MainPrimaryKey getPrimaryKey() {
    return pk;
  }

  public void setPrimaryKey(MainPrimaryKey pk) {
    this.pk = pk;
  }
}

添加新实体

MainDao dao = [...]

// ...

MainPrimaryKey key = new MainPrimaryKey();

ABean aBean = new ABean();
aBean.setName("pinto");

key.setABean(aBean);

Main main = new Main();
main.setPrimaryKey(key);

dao.add(main);

错误

org.springframework.dao.InvalidDataAccessApiUsageException: object references an unsaved transient instance - save the transient instance before flushing: com.blah.persistence.ABean; nested exception is org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.blah.persistence.ABean
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:654)
at org.springframework.orm.hibernate3.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:793)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:664)
[...]

显然,解决方法是首先保存所有依赖项。但是,我绝对不想对实际代码中存在的所有实体都这样做。

关于这里缺少/错误的任何想法?

4

1 回答 1

0

我认为问题可能是这样的:

@Id
@Column(name = "ID")
@Generated(GenerationTime.INSERT)
@GeneratedValue(strategy = GenerationType.AUTO, generator = "a_id_gen")
private long id;

因为 ABean 的 ID 仅在刷新到数据库后才生成,所以它是暂时的(无 id)。所以在保存之前Main需要先保存ABean,然后再保存main。

我建议你删除@Generated(GenerationTime.INSERT). 通常你真的不想要那个!我这样做:

@Id
@GeneratedValue(strategy = GenerationType.AUTO,
        generator = "sequence_generator")
@SequenceGenerator(name = "sequence_generator",
        sequenceName = "my_sequence", allocationSize = 100)
@Column(name = "composition_id")
private Long id;

allocationSize确定在应用程序中缓存了多少序列值。因此,每次插入都不需要数据库之旅来将 id 与新实体相关联。

于 2013-10-30T11:45:30.413 回答