注释反射(使用 getAnnotation)不起作用
我必须按照代码来检查我的 model
中的实体是否在字段上具有 nullable=false
或类似的注释.
I have to following code to check whether the entity in my model
has a nullable=false
or similar annotation on a field.
import javax.persistence.Column;
import .....
private boolean isRequired(Item item, Object propertyId) {
Class<?> property = getPropertyClass(item, propertyId);
final JoinColumn joinAnnotation = property.getAnnotation(JoinColumn.class);
if (null != joinAnnotation) {
return !joinAnnotation.nullable();
}
final Column columnAnnotation = property.getAnnotation(Column.class);
if (null != columnAnnotation) {
return !columnAnnotation.nullable();
}
....
return false;
}
这是我的模型的一个片段.
Here's a snippet from my model.
import javax.persistence.*;
import .....
@Entity
@Table(name="m_contact_details")
public class MContactDetail extends AbstractMasterEntity implements Serializable {
@Column(length=60, nullable=false)
private String address1;
对于那些不熟悉 @Column
注释的人,这里是标题:
For those people unfamiliar with the @Column
annotation, here's the header:
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface Column {
我希望 isRequired
时不时地返回 true
,但它从来没有.我已经在我的项目中完成了 mvn clean
和 mvn install
,但这没有帮助.
I'd expect the isRequired
to return true
every now and again, but instead it never does.
I've already done a mvn clean
and mvn install
on my project, but that does not help.
Q1:我做错了什么?
Q2:是否有更简洁的方式来编写 isRequired
(也许更好地利用泛型)?
Q2: is there a cleaner way to code isRequired
(perhaps making better use of generics)?
-
property
代表一个类(它是一个Class>
) -
@Column
和@JoinColumn
只能注释字段/方法.
-
property
represents a class (it's aClass<?>
) -
@Column
and@JoinColumn
can only annotate fields/methods.
因此,您永远不会在 property
上找到这些注释.
Consequently you will never find these annotations on property
.
稍微修改过的代码版本,打印出是否需要 Employee 实体的 email 属性:
A slightly modified version of your code that prints out whether the email property of the Employee entity is required:
public static void main(String[] args) throws NoSuchFieldException {
System.out.println(isRequired(Employee.class, "email"));
}
private static boolean isRequired(Class<?> entity, String propertyName) throws NoSuchFieldException {
Field property = entity.getDeclaredField(propertyName);
final JoinColumn joinAnnotation = property.getAnnotation(JoinColumn.class);
if (null != joinAnnotation) {
return !joinAnnotation.nullable();
}
final Column columnAnnotation = property.getAnnotation(Column.class);
if (null != columnAnnotation) {
return !columnAnnotation.nullable();
}
return false;
}
请注意,这是一个半生不熟的解决方案,因为 JPA 注释既可以在字段上,也可以在方法上.还要注意 getFiled()
/getDeclaredField()
等反射方法之间的区别.前者也返回继承的字段,而后者只返回特定类的字段,忽略从其父类继承的字段.
Note that this is a half-baked solution, because JPA annotations can either be on a field or on a method. Also be aware of the difference between the reflection methods like getFiled()
/getDeclaredField()
. The former returns inherited fields too, while the latter returns only fields of the specific class ignoring what's inherited from its parents.