【问题标题】:Serializable JPA entity with collection member具有集合成员的可序列化 JPA 实体
【发布时间】:2015-12-30 11:17:32
【问题描述】:

以前的answer 解释说,Findbugz/Sonarqube 警告Non-transient non-serializable instance field in serializable class 应通过在内部使用具体类来修复可序列化类具有成员集合的问题,同时在外部使用(不可序列化)接口。

1 public class SampleClass implements Serializable {
2
3  private static final long serialVersionUID = 1905162041950251407L;
4
5  private Set<Integer> mySet;      // Sonarqube error
6
7  private HashSet<Integer> myOtherSet;
8
9 }

如果该类是我想要使其可序列化的 JPA 实体,该指导是否仍然适用?下面的例子...

 1  @Entity
 2  @Inheritance
 3  @DiscriminatorColumn(name=“fooClass")
 4  @Table(name=“foo”, schema = “bar”)
 5  public class SampleClass implements Serializable {
 6  // SNIP
 7  private static final long serialVersionUID = 1905162041950251407L;
 8
 9  @OneToMany (fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "parent")
10  @MapKey(name = "index")
11  private Map<String, Asset> myMap = new HashMap<>(); // Sonarqube error
12  // SNIP
13 }

编辑 1

澄清问题:

  1. 几乎所有我见过的例子(即使实体是可序列化的) 使用 Collection 接口而不是具体成员,所以我想知道“JPA 世界”中的“正确”方法。
  2. 当我将第 11 行更改为 private HashMap&lt;String, Asset&gt; myMap = ...

为了避免我看到的 FindBugz/Sonarqube 警告

Caused by: org.hibernate.AnnotationException: Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements: 
com.foobar.SampleClass.myMap
    at org.hibernate.cfg.annotations.CollectionBinder.getCollectionBinder(CollectionBinder.java:324) ~[hibernate-core-3.6.10.Final.jar:3.6.10.Final]
    at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:1723) ~[hibernate-core-3.6.10.Final.jar:3.6.10.Final]
    at org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:796) ~[hibernate-core-3.6.10.Final.jar:3.6.10.Final]
    at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:707) ~[hibernate-core-3.6.10.Final.jar:3.6.10.Final]
    at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:4035) ~[hibernate-core-3.6.10.Final.jar:3.6.10.Final]
    at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3989) ~[hibernate-core-3.6.10.Final.jar:3.6.10.Final]
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1398) ~[hibernate-core-3.6.10.Final.jar:3.6.10.Final]
    at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1375) ~[hibernate-core-3.6.10.Final.jar:3.6.10.Final]
    at org.hibernate.ejb.Ejb3Configuration.buildMappings(Ejb3Configuration.java:1519) ~[hibernate-entitymanager-3.6.10.Final.jar:3.6.10.Final]
    at org.hibernate.ejb.EventListenerConfigurator.configure(EventListenerConfigurator.java:193) ~[hibernate-entitymanager-3.6.10.Final.jar:3.6.10.Final]
    at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:1100) ~[hibernate-entitymanager-3.6.10.Final.jar:3.6.10.Final]
    at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:282) ~[hibernate-entitymanager-3.6.10.Final.jar:3.6.10.Final]
    at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:366) ~[hibernate-entitymanager-3.6.10.Final.jar:3.6.10.Final]
    ... 40 

编辑 2 现在,在@Gimby 提示后澄清问题后,我看到了 https://stackoverflow.com/a/8169702/449347那个

从链接 Hibernate 需要持久的集合值 字段被声明为接口类型

所以我猜这只是 Sonarqube/FindBugz 的误报?

【问题讨论】:

  • 我不会将警告称为误报。警告就是:警告。表明某事有合理的可能性引起问题,但不能保证。

标签: java jpa serialization sonarqube


【解决方案1】:

如上述问题中的EDIT 2 所述,Hibernate 3.6 JPA 实现要求将持久集合值字段声明为接口类型。

所以这是静态代码分析工具的误报。

【讨论】:

    猜你喜欢
    • 2015-03-18
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 2016-05-07
    • 1970-01-01
    • 1970-01-01
    • 2015-01-18
    • 2014-04-28
    相关资源
    最近更新 更多