Hibernate返回带有空值的列表(带有List类型的OneToMany注释)

pit*_*chr 6 java mysql hibernate

我遇到一个问题,因为Hibernate(4.1.8.FINAL)返回一个具有NULL值的列表(单向OneToMany映射).

我得到的是: 我得到一个大小为21的List,其中EntryAddress是第10个索引,第二个Entry Address是第20个索引.

Entry [addresses=[null, null, null, null, null, null, null, null, null, null, EntryAddress [id=5, entryId=3, precedence=10, line=Line 3.1], null, null, null, null, null, null, null, null, null, EntryAddress [id=6, entryId=3, precedence=20, line=Line 3.2]]]
Run Code Online (Sandbox Code Playgroud)

我的期望 - 我希望List只有两个EntryAddress对象:

Entry [addresses=[EntryAddress [id=5, entryId=3, precedence=10, line=Line 3.1], EntryAddress [id=6, entryId=3, precedence=20, line=Line 3.2]]]
Run Code Online (Sandbox Code Playgroud)

这是最小的源代码:

@Entity
@Table(name = "entry")
public class Entry {
    ...
    @OneToMany(fetch = FetchType.EAGER, orphanRemoval = true)
    @JoinColumn(name = "entry_id")
    @OrderColumn(name = "precedence")
    private List<EntryAddress> addresses;
    ...
}
Run Code Online (Sandbox Code Playgroud)
@Entity
@Table(name = "entry_address")
public class EntryAddress {
    @Id
    @GeneratedValue
    @Column(name = "id")
    private Integer id;

    @Column(name = "entry_id")
    private Integer entryId;

    @Column(name = "precedence")
    private Integer precedence;
...
}
Run Code Online (Sandbox Code Playgroud)

这是mysql结构(引擎InnoDB):

CREATE TABLE  entry  (
   id  int(10) unsigned NOT NULL AUTO_INCREMENT,
   name  varchar(500) NOT NULL,
   active  int(1) NOT NULL DEFAULT '0',
   modifiedTS  timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
   createdTS  timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY ( id )
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

CREATE TABLE  entry_address  (
   id  int(10) unsigned NOT NULL AUTO_INCREMENT,
   entry_id  int(10) unsigned NULL,
   precedence  int(2) NULL DEFAULT '0',
   line  varchar(255) DEFAULT NULL,
  PRIMARY KEY ( id ),
  UNIQUE KEY  entry_address_uq  ( entry_id , precedence )
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;
Run Code Online (Sandbox Code Playgroud)

当我尝试将"List"替换为"Set"时,集合没有NULL值,但序列/优先级不起作用.

我发现一个有趣的观点是,如果我将1st EntryAddress的优先级设置为1,并将2nd EntryAddress的优先级设置为2,那么我将获得一个大小为2的List.因此,在返回List期间,优先级似乎起作用优先级只应用于排序.

你能告诉我我做错了什么吗?谢谢 :-)

小智 14

从OrderColumn的javadoc:"order列必须是整数类型.持久性提供程序在更新关联或元素集合时维护order列的值的连续(非稀疏)排序.第一个的order列值元素是0."

因此,期望OrderColumn的值从0开始并且是连续值.因此,当值不连续时,Hibernate会将空元素添加到Java列表中.

我认为OrderColumn的这种行为类似于hibernate xml映射中的list-index行为.


pit*_*chr 1

我找到了解决方案,我使用了它,这解决了问题

@OneToMany(orphanRemoval = true)
@LazyCollection(LazyCollectionOption.FALSE)
@JoinColumn(name = "entry_id")
@OrderBy("precedence")
private List<EntryAddress> addresses;

@OneToMany(orphanRemoval = true)
@LazyCollection(LazyCollectionOption.FALSE)
@JoinColumn(name = "entry_id")
@OrderBy("precedence")
private List<EntryContact> contacts;
Run Code Online (Sandbox Code Playgroud)

  • 请扩展您的答案。它的哪一部分解决了您的问题?@LazyCollection? (4认同)