@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();
}
For the error denoted above, I have referred these posts:
These indicate that the value for an annotation must be a compile time constant and a compile time constant can only be a primitive or string. But the error indicated above could be resolved by defining an inner class like so:
@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);
}
}
}
Why am I able to use ReverseStringComparator.class
as the value of @SortedComparator
annotation when it is not a primitive or a String?
Also, is there any other way than defining and using an inner class here (using @SortComparator)?
You can use ReverseStringComparator.class
because that is a class literal, which is explicitly listed as one of the allowed values for an annotation in JLS 9.7.1 Normal Annotations (bold emphasis from source, italic emphasis mine):
It is a compile-time error if the element type is not commensurate with the element value. An element type T is commensurate with an element value v if and only if one of the following is true:
T
is an array typeE[]
, and either:
- [removed for brevity]
T
is not an array type, and the type ofv
is assignment compatible (§5.2) withT
, and:
To highlight the specific rule that applies:
As shown, not only primitive or String is allowed in an annotation, but also a class literal and an enum constant.
To answer your second question: no there is no other way to declare this using @SortComparator
, as it expects a Class
, and as detailed above, then only a class literal is allowed in the annotation.