【问题标题】:Hibernate @OneToOne child not persisting休眠@OneToOne孩子不坚持
【发布时间】:2015-06-10 05:50:50
【问题描述】:

我有一个 Stock 实体,它有 2 个子实体,stock 只能是车辆或财产,不能同时是两者,stock 定义如下:

@RooJavaBean
@RooToString
@RooJpaActiveRecord
public class Stock {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    @Version
    @Column(name = "version")
    private Integer version;

    ...

    @OneToOne(mappedBy = "stock", cascade = CascadeType.ALL)
    private StockProperty property;
    private Boolean isProperty;

    @OneToOne(mappedBy = "stock", cascade = CascadeType.ALL)
    private StockVehicle vehicle;
    private Boolean isVehicle;

    ....

}

然后是子实体StockProperty:

@RooJavaBean
@RooToString
@RooJpaActiveRecord
public class StockProperty {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    @Version
    @Column(name = "version")
    private Integer version;

    ....

    @PrimaryKeyJoinColumn
    @OneToOne(cascade = CascadeType.ALL)
    private Stock stock;

    ... more fields containing property details

}

StockVehicle 遵循完全相同的模式:

@RooJavaBean
@RooToString
@RooJpaActiveRecord
public class StockVehicle {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    @Version
    @Column(name = "version")
    private Integer version;

    ....

    @PrimaryKeyJoinColumn
    @OneToOne(cascade = CascadeType.ALL)
    private Stock stock;

    ... more fields containing vehicle details

}

当试图链接两者时,它在数据库中总是为空:

Stock stock = new Stock();
stock.setProperty(new StockProperty());
stock.getProperty().persist();
stock.persist();

或者反过来说,两边都是空的:

Stock stock = new Stock();

... fill in stock details

StockProperty property = new StockProperty();
property.setStock(stock);
... fill in property details

stock.setProperty(property);
stock.persist();

property.persist();

我没有在日志中看到任何错误,但链接永远不会发生:

Stock 的属性字段全部为空:

StockProperty 的股票字段全部为空:

我正在尝试实现级联删除,所以当我删除 Stock 时,它必须删除 StockProperty,如果可能的话,也可以反过来,否则我会将其设为单向引用。

按要求更新 SQL:

Hibernate: insert into stock (account, company, created, full_description, ..., is_property, is_vehicle, modified, version) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

Hibernate: select last_insert_id()

Hibernate: insert into stock_property (created, modified, ... , version) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

Hibernate: select last_insert_id()

我没有看到股票插入 sql 中的属性字段,我也没有看到 stock_property 的插入 sql 中的股票字段。

【问题讨论】:

  • 不,用一个例子更新了我的问题,我试图手动将它双向链接但没有成功。
  • 我不知道SpringRoo 是如何工作的,但似乎很有侵略性。无论如何,我希望在所有候选持久性的类上看到@Entityannotations。使用日志记录/调试器,您应该能够看到 SQL 用于插入。可以贴一下吗?
  • 这个逻辑是否在一个用@Transactional注解的非静态方法上?
  • 尝试去掉@PrimaryKeyJoinColumn注解:我觉得你不需要。

标签: java spring hibernate jpa spring-roo


【解决方案1】:

在 StockProperty 上试试这个:

@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "idStock", nullable = false)
private Stock stock;

还有这个库存:

@OneToOne(mappedBy="stock")
private StockProperty stockProperty;

【讨论】:

  • 我已经删除了我的架构并让 hibernate 创建一个新架构,它现在正在工作,除了删除。 Hibernate 在两个表之间添加了外键约束,现在如果我想删除其中任何一个中的一行,由于外键约束,它会失败。
  • 删除 @JoinColumn 删除了不允许我删除的严格外键约束,我现在可以先删除 StockProperty,然后删除 Stock 并且它可以工作。
猜你喜欢
  • 2021-12-07
  • 2017-06-25
  • 1970-01-01
  • 1970-01-01
  • 2013-10-28
  • 2011-02-13
  • 2021-06-25
  • 2012-10-14
相关资源
最近更新 更多