有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

@EmbeddedId中的java实体在用作@EmbeddedId时忽略级联注释

我不喜欢发布一个被问了1000次的问题,就像你不喜欢读这些重复的问题一样多(如果不是更多的话)。。。但我现在被难倒了。我不明白为什么所有这些帖子中的典型解决方案,即使用'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)
[...]

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

你知道这里缺了什么/出了什么问题吗


共 (1) 个答案

  1. # 1 楼答案

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

    @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与一个新实体关联时,都不需要数据库访问