属性值必须是常量

问题描述 投票:0回答:1
@Entity
@Table(name = "student")
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    // other fields

    @ElementCollection
    @CollectionTable(name = "studentImages")
    @MapKeyColumn(name = "file_name")
    @SortComparator(reverseSort.getClass()) // Error: Attribute value must be a constant
    @Column(name = "img_desc")
    private Map<String, String> images = new TreeMap<>();

    private static Comparator<String> reverseSort = Comparator.reverseOrder();
}

对于上述错误,我参考了这些帖子:

这些表明注释的值必须是编译时常量,并且编译时常量只能是基元或字符串。但是上面指出的错误可以通过定义一个内部类来解决,如下所示:

@Entity
@Table(name = "student")
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    // other fields

    @ElementCollection
    @CollectionTable(name = "studentImages")
    @MapKeyColumn(name = "file_name")
    @SortComparator(ReverseStringComparator.class) // Is this a compile time constant?
    @Column(name = "img_desc")
    private Map<String, String> images = new TreeMap<>();

    private class ReverseStringComparator implements Comparator<String> {
        @Override
        public int compare(String o1, String o2) {
            return o2.compareTo(o1);
        }
    }
}

当它不是基元或字符串时,为什么我可以使用

ReverseStringComparator.class
作为
@SortedComparator
注释的值? 另外,除了在这里定义和使用内部类(使用@SortComparator)之外,还有其他方法吗?

java hibernate annotations hibernate-mapping
1个回答
0
投票

您可以使用

ReverseStringComparator.class
,因为这是一个类文字,它在JLS 9.7.1普通注释中被明确列为注释的允许值之一(来源中的粗体强调,我的斜体强调):

如果元素类型与元素值不相称,则会出现编译时错误。元素类型 T 与 元素值 v 当且仅当以下条件之一为真时:

  • T
    是数组类型
    E[]
    ,并且:

    • [为了简洁而删除]
  • T
    不是数组类型,并且
    v
    的类型与 T 是赋值兼容的 (
    §5.2
    ),并且:

    • 如果
      T
      是原始类型或
      String
      ,则
      v
      是常量表达式 (§15.29)。
    • 如果
      T
      Class
      或对
      Class
      (§4.5) 的调用,则
      v
      是类文字 (§15.8.2)。
    • 如果
      T
      是枚举类类型 (§8.9),则
      v
      是枚举常量 (§8.9.1)。
    • v
      不是
      null

突出显示适用的具体规则:

  • 如果
    T
    Class
    或对
    Class
    (§4.5) 的调用,则
    v
    是类文字 (§15.8.2)。

如图所示,注释中不仅允许基元或字符串,还允许类文字和枚举常量。

© www.soinside.com 2019 - 2024. All rights reserved.