Идентификатор автоинкремента не отображается в составном ключе с использованием JPA - PullRequest
2 голосов
/ 27 января 2011

У меня есть отображение ниже

@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 будет установлен автоматически (может быть последним вставленным идентификатором))

но я получаю ошибку ниже, я не уверен, почему в аукционе идентификатор аукциона имеет значение 0, а не последний идентификатор на аукционе (я использую 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, а не как последний вставленный идентификатор: (

В чем проблема с этим отображением?

Ответы [ 2 ]

2 голосов
/ 27 января 2011

@GeneratedValue будет устанавливать значение атрибута, для которого он аннотирован, только если у вас есть другие атрибуты в других классах, которые ссылаются на идентификатор, за который вы отвечаете за их установку.

т.е. вам нужно будет сначала сохранить и сбросить аукцион, а затем создать AuctionParamValue, используя его идентификатор генерации.

Или, если вы использовали генерацию идентификатора TABLE или SEQUENCE, вам просто нужно вызвать persist, а не flush. В общем, я бы никогда не рекомендовал секвенирование IDENTITY, поскольку его значения не могут быть предварительно распределены.

Но на самом деле вы не должны иметь повторяющиеся поля, как все. Полностью удалите @EmbeddedId auctionParamValuePK и просто добавьте @Id к двум @ManyToOnes и используйте вместо него @IdClass. Это значительно упростит работу и будет работать даже при генерации идентификатора IDENTITY.

Вы также можете вместо этого удалить вставляемый / обновляемый = ложный для двух отображений @ManyToOne и вместо этого поместить их в атрибуты @EmbeddedId, это будет иметь внешний ключ, записанный из отношений, но ваш объект все равно будет поврежден в памяти .

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

0 голосов
/ 27 января 2011

Вы можете попробовать две вещи:

  • делает два идентификатора обнуляемыми: используйте Типы-обертки вместо примитивов (Integer, Long) и установите его в null перед сохранением
  • оставьте комбинированное поле Primary ID (auctionParamValuePK) пустым (ноль) при его сохранении.

Я не знаю, решит ли это проблему, но я уверен, что вам нужно сделать хотя бы один из них, чтобы она заработала.

...