注释反射(使用getAnnotation)不起作用

时间:2013-02-19 18:48:40

标签: java jpa reflection annotations persistence

我必须按照代码检查model中的实体是否在字段上有nullable=false或类似的注释。

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;
    }

这是我模特的片段。

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注释的人,这里是标题:

@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface Column {

我希望isRequired一次又一次地返回true,但它永远不会。 我已经在我的项目中完成了mvn cleanmvn install,但这没有帮助。

Q1:我做错了什么?

Q2:是否有一种更简洁的方式来编码isRequired(也许更好地利用泛型)?

2 个答案:

答案 0 :(得分:4)

  1. property代表一个类(它是Class<?>
  2. @Column@JoinColumn只能注释字段/方法。
  3. 因此,您永远不会在property上找到这些注释。

    稍微修改过的代码版本,用于打印出是否需​​要Employee实体的email属性:

    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()等反射方法之间的区别。前者也返回继承的字段,而后者只返回特定类的字段,忽略从父节点继承的字段。

答案 1 :(得分:0)

以下代码有效:

    @SuppressWarnings("rawtypes")
    private boolean isRequired(BeanItem item, Object propertyId) throws SecurityException {

        String fieldname = propertyId.toString();

        try {
            java.lang.reflect.Field field = item.getBean().getClass().getDeclaredField(fieldname);
            final JoinColumn joinAnnotation = field.getAnnotation(JoinColumn.class);
            if (null != joinAnnotation) {
                return !joinAnnotation.nullable();
            }

            final Column columnAnnotation = field.getAnnotation(Column.class);
            if (null != columnAnnotation) {
                return !columnAnnotation.nullable();
            }



        } catch (NoSuchFieldException e) {
            //not a problem no need to log this event.
            return false;
        } 
    }