【问题标题】:autoincrement id is not reflecting in composite key using JPA自动增量 ID 未反映在使用 JPA 的复合键中
【发布时间】:2011-01-27 07:29:47
【问题描述】:

我有一个下面的映射

@Entity
@Table(name = "auctions")
public class Auction{
.
.
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "auction")
    private List<AuctionParamValue> auctionParamValueList;
.
.
}


@Entity
@Table(name = "auction_param_values")
public class AuctionParamValue {

    @EmbeddedId
    protected AuctionParamValuePK auctionParamValuePK;

    @JoinColumn(name = "auction_param_id", referencedColumnName = "auction_param_id",updatable=false,insertable=false)
    @ManyToOne @MapsId("auctionParamId")
        private AuctionParam auctionParam;

    @JoinColumn(name = "auction_id", referencedColumnName  = "auction_id",updatable=false,insertable=false)
    @ManyToOne @MapsId("auctionId") 
        private Auction auction;
}

@Embeddable
public class AuctionParamValuePK {

@Id
@Basic(optional = false)
       @Column(name = "auction_id")
       @Nullable
       private Long auctionId = null;

@Id
       @Basic(optional = false)
       @Column(name = "auction_param_id")
       @Nullable
       private Long auctionParamId = null;    
}

@Entity
@Table(name = "auction_params")    
public class AuctionParam {
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "auctionParam")
    private List<AuctionTypeParam> auctionTypeParamList;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "auctionParam")
    private List<AuctionParamValue> auctionParamValueList;
 }

}

当我尝试坚持拍卖时(我手动设置了auctionParamId 并期望自动设置auctionId(可能是最后插入的id))

但是我遇到了错误,我不确定为什么查询中的auctionId 在拍卖中是0 而不是最新的id。(我正在使用eclipselink jpa 提供程序)

Internal Exception: com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`portaldemo`.`auction_param_values`, CONSTRAINT `auction_param_values_auction_id_fk` FOREIGN KEY (`auction_id`) REFERENCES `auctions` (`auction_id`))
Error Code: 1452
Call: INSERT INTO auction_param_values (auction_param_val, create_ts, last_updt_ts, auction_param_id, auction_id) VALUES (?, ?, ?, ?, ?)
    bind => [2011-02-12 04:00:00, 2011-01-27 12:02:00.28, 2011-01-27 12:17:43.25, 2, 0]
Query: InsertObjectQuery(com.eaportal.domain.AuctionParamValue[auctionParamValuePK=com.eaportal.domain.AuctionParamValuePK[auctionId=0, auctionParamId=2]])

这里 [auctionId=0 总是以 0 的形式出现,而不是最后插入的 id :(

这个映射有什么问题?

【问题讨论】:

    标签: orm jpa eclipselink


    【解决方案1】:

    @GeneratedValue 只会设置它被注释的属性的值,如果您在其他类中有其他属性引用您负责设置这些的 id。

    即您需要先持久化并刷新 Auction,然后使用其生成 Id 创建 AuctionParamValue。

    或者,如果您使用 TABLE 或 SEQUENCE id 生成,那么您只需要调用persist,而不是flush。一般来说,我永远不会推荐 IDENTITY 排序,因为它的值不能预先分配。

    但实际上你不应该有重复的字段。完全删除@EmbeddedId 拍卖ParamValuePK,只需将@Id 添加到两个@ManyToOne,并改用@IdClass。这将使事情变得更加简单,并且可以正常工作,即使生成 IDENTITY id 也是如此。

    您也可以删除两个 @ManyToOne 映射上的 insertable/updateable=false 并将它们放在 @EmbeddedId 属性上,这将具有从关系中写入的外键,但您的对象仍将在内存中损坏.

    看, http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#Primary_Keys_through_OneToOne_and_ManyToOne_Relationships

    【讨论】:

      【解决方案2】:

      你可以尝试两件事:

      • 使两个 id 可以为空:使用包装类型而不是原始类型(整数、长整数),并在保存前将其设置为 null
      • 保存时将组合的主 ID 字段 (auctionParamValuePK) 留空 (null)。

      我不知道这是否能解决问题,但我确信您至少需要执行其中一项才能使其正常工作。

      【讨论】:

      • 我尝试了这两件事,第一点在帖子(问题)中更新,现在我在插入查询中将auction_id 和auction_param_id 都设为null。还有什么我做错了吗?
      • @Sourabh:您的数据库列是自增列吗?
      猜你喜欢
      • 2017-04-27
      • 2017-02-25
      • 2012-10-15
      • 2013-08-09
      • 2012-08-11
      • 2014-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多