Grails "отображать как XML" создает исключение java.lang.NullPointerException - что я делаю не так? - PullRequest
0 голосов
/ 13 октября 2010

Я использую следующий код Grails для визуализации коллекции SomeClass -объектов в виде XML:

def someObjects = SomeClass.findAllByFoo(foo)
if (someObjects) {
  render(contentType:"text/xml", text:someObjects as XML)
}

Это работает, как и ожидалось, большую часть времени. Однако иногда и в зависимости от содержимого некоторых объектов код завершается ошибкой со следующим NullPointerException (обратите внимание, что someObjects != null):

java.lang.NullPointerException
    at grails.converters.XML.getElementName(XML.java:128)
    at grails.converters.XML.convertAnother(XML.java:163)
    at grails.converters.XML.convertAnother(XML.java:163)
    at grails.converters.XML.convertAnother(XML.java:163)
    at grails.converters.XML.render(XML.java:111)
    at grails.converters.XML.toString(XML.java:281)
    at project.SomethingController$_closure8.doCall(project.SomethingController:217)
    at project.SomethingController$_closure8.doCall(project.SomethingController)
    at java.lang.Thread.run(Thread.java:637)

Это определение класса SomeClass:

class SomeClass {
  List<A> a = new ArrayList<A>()
  List<B> b = new ArrayList<B>()
  List<C> c = new ArrayList<C>()
  static hasMany = [a : A, b : B, c : C]
}

Я обнаружил, что исключения можно избежать, просто изменив определение SomeClass на:

class SomeClass {
  def a = new ArrayList<A>()
  def b = new ArrayList<B>()
  def c = new ArrayList<C>()
  static hasMany = [a : A, b : B, c : C]
}

Мои вопросы:

  • Что я делаю неправильно во взаимодействии с "render as XML"? Ожидается ли здесь NPE?
  • Почему последнее определение SomeClass работает, а первое - нет?

1 Ответ

1 голос
/ 13 октября 2010

кажется, что проблема в определении, потому что конвертер XML не может преобразовать нулевой элемент (целое поле или просто элемент списка).

class SomeClass {
  List<A> a = new ArrayList<A>()
  List<B> b = new ArrayList<B>()
  List<C> c = new ArrayList<C>()
  static hasMany = [a : A, b : B, c : C]
}

Действительно странное определение. static hasMany = [a: A, b: B, c: C] пытается создать три поля a, b, c , и каждое поле имеет тип java.util.Set .Просто попробуйте это определение:

    class SomeClass {
      static hasMany = 
       [
            a : A, 
            b : B, 
            c : C
       ]
    }

Все должно быть в порядке.

Ваш пример:

class SomeClass {
  def a = new ArrayList<A>()
  def b = new ArrayList<B>()
  def c = new ArrayList<C>()
  static hasMany = [a : A, b : B, c : C]
}

работает из-за характера динамической типизации.Здесь нет строгой проверки типов, и переменные можно легко переназначить на другой тип.

...