2014-09-09 5 views
0

Я только начинаю с Grails (из Rails), и я заметил, что Grails действительно не похоже на модификаторы областей на поля в классах домена.Почему модификаторы областей в полях в классах домена предотвращают проверку?

Я понял, что все поля без полей в классе домена по умолчанию были общедоступны, но если вы действительно объявите его общедоступным, Grails не будет его проверять.

class Person { 
    public String firstName 
    public String middleName 
    public String lastName 
} 

Если добавить ограничение, Grails выбросит исключение NotReadablePropertyException при вызове Validate()

class Person { 
    public String firstName 
    public String middleName 
    public String lastName 

    static constraints = { 
    middleName nullable: true 
    } 
} 

Однако, если вы берете на публичное заявление, все работает нормально.

Может кто-нибудь объяснить, что происходит за кулисами, с областью определения областей домена? Трудно понять, почему явным образом объявляю что-то публичное, которое уже открыто, нарушит структуру. Я предполагаю, что вы также не захотите объявлять что-либо «частным», хотя было бы неплохо, если бы не было того, что поля, которые нельзя манипулировать напрямую, могут быть скрыты от потребителей класса домена.

ответ

4

При добавлении поля в Groovy класса без модификатора области видимости, это более, что это вывод быть публичным, чем быть на самом деле общественность. Компилятор преобразует поле в частное поле и генерирует для него публичный получатель и сеттер, хотя он не будет перезаписывать получателя или сеттер, которые вы написали. Это удобно, потому что позже вы можете создавать геттеры и/или сеттеры для реализации бизнес-логики и не влиять на вызывающих.

Но публичное поле (объявленное как «общественное») - это просто публичное поле. Там нет сгенерированного геттера или сеттера. Я рекомендую использовать декомпилятор, чтобы увидеть это в действии - создать простой POGO в src/groovy, например.

class Thing { 
    String realProperty 
    public String fieldButNotProperty 
} 

и открыть файл .class с http://jd.benow.ca/ или другим декомпилятором.

GORM автоматически предполагает, что типизированные свойства являются постоянными, если вы не исключили некоторые из них в список transients. Тип необходим, чтобы он знал, как сохранить данные, а свойства, такие как def name, будут игнорироваться. Свойства в этом смысле аналогичны свойствам JavaBean - сопоставимой парой getter/setter.

Hibernate не поддерживает Groovy и не знает, что происходит под капотом - он просто называет ваши геттеры и сеттеры для установки и доступа к данным поля во время сохранения.Таким образом, компилятор Groovy, добавляющий те, что облегчает для POGO в Grails, сохраняется Hibernate. И вы можете сделать это самостоятельно - добавить в геттер и сеттер с правильными именами и типом данных (например String getName() и void setName(String name) и будут рассматриваться в качестве постоянного жилья, даже если вы ничего не делаете со значениями

Причиной, побуждающей. NotReadablePropertyException - это то, что у вас нет доступа для вашего свойства. Несмотря на то, что ваши поля совершенно доступны, вы фактически скрыли их от GORM и Hibernate.

+0

Спасибо. один был головным скребком, но это имеет смысл. – user1023110

+0

PS ... просто понял, что вы парень, который написал книгу «Программирование Грааля», которую я сейчас только что купил. (Другие, я, кажется, пропустил, как магия выполняется так сложно, чтобы сказать, что происходит на самом деле.) – user1023110

0

Если добавить ограничение, Grails выбросит исключение NotReadablePropertyException при вызове Validate()

Никогда не замечал этого раньше, звучит как ошибка

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

Если вы хотите предотвратить прямой доступ к собственности, просто добавьте геттер и сеттер. В приведенном ниже примере я гарантирую, что имя всегда читается/записывается как строка верхнего регистра.

class Person { 
    public String firstName 
    public String middleName 
    public String lastName 

    public void setFirstName(String name) { 
    this.firstName = name.toUpperCase() 
    } 

    public String getFirstName() { 
    return this.firstName.toUpperCase() 
    } 
} 
+0

Ну, я думал, это может быть ошибка, но это было довольно сложный в моей тестовой жгуте (GroovyTestCase). Если у вас есть минута, можете ли вы сообщить мне, если поставить это в модульном тесте, что person.veryify() выдает исключение, если у вас есть ограничения cluse, такие как firstName blank: false или что-то еще. – user1023110

 Смежные вопросы

  • Нет связанных вопросов^_^