Когда PropertyUtils.copyProperties может произойти сбой молча? - PullRequest
3 голосов
/ 05 декабря 2011

Я использую PropertyUtils.copyProperties () для копирования свойств объекта с помощью отражения, и раньше он работал хорошо.Однако недавно он начал ничего не делать.

Он не выдает исключение, а просто не будет копировать поля.Все поля целевого объекта остаются нулевыми, хотя в исходных объектах есть ненулевые поля.

Я не знаю, как воспроизвести это.Для меня это происходит последовательно, но это внутри проекта, который я не могу просто опубликовать здесь.В проекте используется Play Framework, который выполняет некоторые манипуляции с байт-кодом, поэтому он может быть виновником.

Любые советы или идеи о том, что может быть причиной, или как отлаживать?Также приветствуются альтернативные копировщики полей (я пробовал BeanUtils однажды, но переключился на PropertyUtils из-за некоторого предостережения, которое я сейчас не помню).

Ответы [ 3 ]

2 голосов
/ 22 марта 2012

Думаю, я понял это.Это случилось со мной сегодня.Я просто сделал небольшой тест, и он не сработал.Вот код:

 static class TesteP {

    private String a;
    private String b;
    private String c;

    public String getA() {
        return this.a;
    }


    public void setA(String a) {
        this.a = a;
    }



    public String getB() {
        return this.b;
    }


    public void setB(String b) {
        this.b = b;
    }


    public String getC() {
        return this.c;
    }


    public void setC(String c) {
        this.c = c;
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this.getClass()).add("a", this.a).add("b", this.b).toString();
    }

}

 static class RestP {

    private String a;

    public String getA() {
        return this.a;
    }

    public void setA(String a) {
        this.a = a;
    }

    @Override
    public String toString() {
        return this.a;
    }
}

public static void main(String[] args)
        throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
    TesteP p = new TesteP();
    p.setA("AAAA");
    p.setB("BBB");
    TesteP pp = new TesteP();
    RestP p2 = new RestP();
    p2.setA("aaaa");
    PropertyUtils.copyProperties(p,p2);

}

Это решило проблему, сделав классы общедоступными.Возможно, один из ваших классов не публичный.Вот решение в моем случае:

 public static class TesteP {

    private String a;
    private String b;
    private String c;


    public String getA() {
        return this.a;
    }


    public void setA(String a) {
        this.a = a;
    }


    public String getB() {
        return this.b;
    }


    public void setB(String b) {
        this.b = b;
    }


    public String getC() {
        return this.c;
    }


    public void setC(String c) {
        this.c = c;
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this.getClass()).add("a", this.a).add("b", this.b).toString();
    }

}

 public static class RestP {

    private String a;

    public String getA() {
        return this.a;
    }

    public void setA(String a) {
        this.a = a;
    }

    @Override
    public String toString() {
        return this.a;
    }
}

public static void main(String[] args)
        throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
    TesteP p = new TesteP();
    p.setA("AAAA");
    p.setB("BBB");
    TesteP pp = new TesteP();
    RestP p2 = new RestP();
    p2.setA("aaaa");
    PropertyUtils.copyProperties(p,p2);

}
1 голос
/ 05 декабря 2011

Я взял код из этого ответа и запустил его, он потерпел неудачу из-за того, что у меня было поле только для записи (только установщик, но не получатель). Скорее всего, это то, что портит PropertyUtils.

Я обнаружил, что вызов Introspector.getBeanInfo(MyModel.class).getPropertyDescriptors() возвращает только частичный список свойств. Воспроизводится на этом репозитории github .

Я добавил вызов Introspector.flushCaches();, надеясь, что это решит проблему ... только это не так.

В качестве обходного пути я реализовал метод копирования полей вместо ответа на beanutils:

public static <T> void copyFields(T target, T source) throws Exception{
    Class<?> clazz = source.getClass();

    for (Field field : clazz.getFields()) {
        Object value = field.get(source);
        field.set(target, value);
    }
}
0 голосов
/ 05 декабря 2011

Dozer - более сложный копир бобов, который вы, возможно, захотите попробовать.

Чтобы отладить проблему PropertyUtils, создайте модульный тест, а затем пройдитесь по нему.

...