LINUX.ORG.RU

Релиз Grails 1.0

 , , ,


0

0

G2One Inc — компания разработчиков Groovy и Grails — рады объявить о выпуске Grails v.1.0.

Grails является фреймворком для создания динамических веб-приложений на базе платформы Java и языка программирования Groovy. В нём реализованы лучшие решения из Java EE, в том числе Spring, Hibernate и SiteMesh.

В новом релизе:

  • GORM поддерживает Object Relational Mapping (ORM) Domain Specific Language (DSL) для сложного маппинга
  • простое использование объектов-фильтров (Filters)
  • автоматическое определение формата выходных данных (Content Negotiation)
  • поддержка REST
  • поддержка JNDI

>>> Полный список изменений
>>> Документация
>>> Страница загрузки

>>> Подробности

★★★★★

Проверено: Shaman007 ()

Только вчера скачал RC, оно немного глючит в некоторых местах.

Для тех, кто ещё не наступал на грабли - GRAILS_HOME должна быть указана без закрывающего слеша.

Aceler ★★★★★
()
Ответ на: комментарий от Aceler

Это ты по какой доке делал со слешем то ?
Я по доке с родного сайта делал ... нету тама слеша ...

У меня вот вопрос ... я раньше думал что оно использует
java через groovy но у меня сейчас не установлен groovy а
а только JDK так тем не менее пример сделался и war собрался ...

Так каким боком groovy к grails относиться ?
--
mx

anonymous
()
Ответ на: комментарий от Bohtvaroh

> какие нарыли грабли

http://rsdn.ru/Forum/message/2721991.flat.aspx

Была ещё одна бага, hibernate в лог пишет много ругани, но гугленье выявило, что это неопасно. В общем лог засоряет и людей пугает.

> чем версия из svn кошерней стабильного релиза? :)

Не знаю, сейчас времени нет тестировать, но второй баг там точно исправлен.

Ещё жутко бесят неинформативные ошибки из за кривых маппингов, которые изредка появляются, и их причину можно найти, только перелопатив исходники hibernate-а.

PS тем не менее юзаем, куда деваться, штука то хорошая.

Legioner ★★★★★
()
Ответ на: комментарий от Bohtvaroh

Ещё весьма не порадовало то, что он при запросе всегда результаты в память считывает, с большими объёмами данных это очень расточительно. Мог бы подгружать по мере движения итератора.

Legioner ★★★★★
()

Очень кошерно, на днях собираюсь это все осилить. Просто замечательно.

anonymous
()
Ответ на: комментарий от Legioner

Ну как правило для связи MANY-TO-MANY хибернейт создаёт третью таблицу. У вас, я так понял, жёсткая существующая структура к которой пришлось приделывать костыль, оттудова и грабли. Дальше особо не разбирался, прошу простить если не прав. :)

Bohtvaroh ★★★★
()
Ответ на: комментарий от Legioner

> Ещё весьма не порадовало то, что он при запросе всегда результаты в память считывает, с большими объёмами данных это очень расточительно. Мог бы подгружать по мере движения итератора.

http://www.hibernate.org/hib_docs/v3/api/org/hibernate/Query.html#iterate()

Return the query results as an Iterator. If the query contains multiple results pre row, the results are returned in an instance of Object[].

Entities returned as results are initialized on demand. The first SQL query returns identifiers only.

То есть, это не работает?

Судя по моему опыту, проблемы с hibernate связаны с непониманием работы оного, я не "мега-спец", как раз в процессе упорядочивания навыков прочтением "Java persistence with Hibernate". :)

Bohtvaroh ★★★★
()
Ответ на: комментарий от Bohtvaroh

> http://www.hibernate.org/hib_docs/v3/api/org/hibernate/Query.html#iterate()

Этого хотелось бы для Criteria API. HQL не так удобен.

Честно говоря могу ошибаться, но кажется этот iterate тоже загружает всё сразу. Сейчас разберусь, отпишусь.

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

> Честно говоря могу ошибаться, но кажется этот iterate тоже загружает всё сразу. Сейчас разберусь, отпишусь.

Только учитывай также параметр lazy-init.

Bohtvaroh ★★★★
()
Ответ на: комментарий от Legioner

>Hibernate глючный :(

Hibernate достаточно стабильный.
Баги есть в любом софте - grails не исключение(в нём их как понимате будет даже больше).

Yilativs ★★★★
()
Ответ на: комментарий от Legioner

>Мужики сурово пишут вокэраунды или юзают версию из svn-а

Можешь постить баги прямо сюда (только коменты in english),
я их передам разработчикам Hibernate (я пишу софт для достаточно крупного клиента RedHat/JBoss, есть возможность общать hibernate девелоперов).

Yilativs ★★★★
()
Ответ на: комментарий от Yilativs

Database DDL:

CREATE TABLE VSB.ADDRESS
 (ADDRESSID    INTEGER         NOT NULL  PRIMARY KEY,
  ADDRESS      VARCHAR(64)     NOT NULL,
  ADDRESSCODE  INTEGER         NOT NULL
 );

CREATE TABLE VSB.PERSON
 (PERSONID           INTEGER         NOT NULL  PRIMARY KEY,
  PERSONNAME         VARCHAR(32)     NOT NULL,
  PERSONADDRESSCODE  INTEGER         NOT NULL
 );


Row in the Person linked to the address via field PERSONALADDRESSCODE;
ADDRESS.ADDRESSCODE can have dublicates, so it's many-to-many relationship.

Java code:

public class Person {
    private Integer id;
    private String name;
    private Integer addressCode;
    private Set addresses;
// getters and setters
}

public class Address {
    private Integer id;
    private String address;
// getters and setters
}


Hibernate mappings:

<hibernate-mapping package="htest" schema="vsb">
  <class name="Person" table="PERSON">
    <id name="id" column="PERSONID"/>
    <property name="name" column="PERSONNAME"/>
    <property name="addressCode" column="PERSONADDRESSCODE"/>
    <set name="addresses" fetch="join" >
      <key column="ADDRESSCODE" property-ref="addressCode"/>
      <one-to-many class="Address"/>
    </set>
  </class>
</hibernate-mapping>

<hibernate-mapping package="htest" schema="vsb">
  <class name="Address" table="Address">
    <id name="id" column="ADDRESSID"/>
    <property name="address" column="ADDRESS"/>
<!--     <property name="code" column="ADDRESSCODE"/>-->
  </class>
</hibernate-mapping>


But it doesn't work:

    public static void main(final String[] args) {
        Session session = new Configuration().configure().buildSessionFactory().getCurrentSession();
        session.beginTransaction();
        List persons = session.createCriteria(Person.class).list();
        for (Iterator iterPerson = persons.iterator(); iterPerson.hasNext();) {
            Person person = (Person) iterPerson.next();
            System.out.println("Name: " + person.getName());
            for (Iterator iterAddress = person.getAddresses().iterator(); iterAddress.hasNext();) {
                Address address = (Address) iterAddress.next();
                System.out.println("  " + address.getAddress());
            }
        }
        session.flush(); // bug
        session.getTransaction().commit();
    }


Throws at line with flush with the following stacktrace:

Exception in thread "main" org.hibernate.HibernateException: Found shared references to a collection: htest.Person.addresses
    at org.hibernate.engine.Collections.processReachableCollection(Collections.java:16
3)
    at org.hibernate.event.def.FlushVisitor.processCollection(FlushVisitor.java:37)
    at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:101)
    at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:61)
    at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVis
itor.java:55)
    at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFl
ushEntityEventListener.java:138)
    at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlu
shingEventListener.java:196)
    at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutio
ns(AbstractFlushingEventListener.java:76)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventList
ener.java:26)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.ja
va:43)
    at java.lang.reflect.Method.invoke(Method.java:615)
    at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.in
voke(ThreadLocalSessionContext.java:301)
    at $Proxy0.flush(Unknown Source)
    at htest.Main.main(Main.java:28)



if fetch is changed to: fetch="select", even more interesting exception is thrown:

Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: htest.Person.addresses, no session or session was closed
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationEx
ception(AbstractPersistentCollection.java:358)
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationEx
ceptionIfNotConnected(AbstractPersistentCollection.java:350)
    at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersis
tentCollection.java:343)
    at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCo
llection.java:86)
    at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:163)
    at htest.Main.main(Main.java:23)

This behavior was tested on hibernate 3.2.5 with database IBM DB2.

Calling session.clear before flush solves the problem.

Английский хромает, знаю. Чукча читатель :) Только этот баг кажется у них в багзилле есть. Сейчас правда найти не могу.

Legioner ★★★★★
()
Ответ на: комментарий от Yilativs

> На что только не идут люди что бы не использовать Hibernate/Spring/GWT...

"В нём реализованы лучшие решения из Java EE, в том числе Spring, Hibernate и SiteMesh."

Кто из вас двоих ошибается?

sv75 ★★★★★
()
Ответ на: комментарий от anonymous

> Это ты по какой доке делал со слешем то ?

По книжке из предыдущей новости. Там тоже нет слеша, но разве это помеха для настоящего джигита?

Aceler ★★★★★
()
Ответ на: комментарий от anonymous

> Так каким боком groovy к grails относиться ?

Groovy - это язык. Программы, написанные на groovy, компилируются в Java bytecode и исполняются на Java Virtual Machine, поэтому вам нужны только JRE и JDK.

Aceler ★★★★★
()
Ответ на: комментарий от sv75

> На что только не идут люди что бы не использовать
> Hibernate/Spring/GWT...

Мне кажеться он пропустил слово "напрямую"

to Yilativs :
А вот у меня вопрос ( просто интересно )
и какая сейчас java у Шапки в ходу ?
например в Федоре по умолчанию сразу 2 ставят
( 150-gcj и 170-free ) а ведь можно еще сановскую 160_04
приплести ....

--
mx

anonymous
()

>Hibernate

Ололололо :) Это такая вещь, которая для того, чтобы сделать SELECT a, b, c FROM foo WHERE bar = 1, требует кучу конфигурации в XML и полтысячи строк кода в исходнике.

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

Отличная, отличная технология. Для полноты картины не хватает только XSLT преобрпзователя.

anonymous
()
Ответ на: комментарий от Aceler

а кто их компилирует в java байт код ?
В Grails создаються и юзаються файлы : name.groovy

--
mx

anonymous
()
Ответ на: комментарий от Bohtvaroh

Всё, понял почему мне iterate не понравился. Далее предполагаем, что мне надо обработать 20 миллионов записей, причём мне они все сразу не нужны.

Он делает так:

select person0_.ID as col_0_0_ from PERSON person0_

т.е. здесь уже скушали мегабайтов сто памяти.

и потом на каждом шагу

select person0_.ID as ID0_0_, person0_.NAME as NAME0_0_ from PERSON person0_ where person0_.ID=?

select person0_.ID as ID0_0_, person0_.NAME as NAME0_0_ from PERSON person0_ where person0_.ID=?

select person0_.ID as ID0_0_, person0_.NAME as NAME0_0_ from PERSON person0_ where person0_.ID=?

т.е. память больше не кушаем, но к базе идёт отдельный запрос на каждый next итератора.

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

>т.е. здесь уже скушали мегабайтов сто памяти.

>и потом на каждом шагу

Ваааааааауууууууууу!!!1111адинадинадинадин

Реализация работы с БД в лучших традицЫях похапэбыдлокодеров - по запросу на итерацию.

anonymous
()
Ответ на: комментарий от anonymous

> Реализация работы с БД в лучших традицЫях похапэбыдлокодеров - по запросу на итерацию.

Ты действительно не можешь придумать юз-кейза, где такое необходимо? Тогда да, "в лучших традицЫях похапэбыдлокодеров".

Bohtvaroh ★★★★
()
Ответ на: комментарий от Legioner

> Всё, понял почему мне iterate не понравился.

А как бы сделали Вы? Напишите свой приблизительный вариант на SQL того, что бы вам хотелось от Hibernate в данном случае. :)

Bohtvaroh ★★★★
()
Ответ на: комментарий от Bohtvaroh

>> Реализация работы с БД в лучших традицЫях похапэбыдлокодеров - по запросу на итерацию.

>Ты действительно не можешь придумать юз-кейза, где такое необходимо? Тогда да, "в лучших традицЫях похапэбыдлокодеров".

select person0_.ID as col_0_0_ from PERSON person0_

select person0_.ID as ID0_0_, person0_.NAME as NAME0_0_ from PERSON person0_ where person0_.ID=?

select person0_.ID as ID0_0_, person0_.NAME as NAME0_0_ from PERSON person0_ where person0_.ID=?

select person0_.ID as ID0_0_, person0_.NAME as NAME0_0_ from PERSON person0_ where person0_.ID=?

Детка, ТАКИХ юзкейзхов в нормальном проекте быть не должно. Открой для себя волшебство курсоров и не пользуйся больше этим унылым гафном.

anonymous
()
Ответ на: комментарий от Bohtvaroh

>При этом учитывая, что не все СУБД поддерживают порционность получения данных, как, например, LIMIT в MySQL.

Не все СУБД поддерживают полнотекстовый поиск, давайте вместо него напишем свое УГ.

anonymous
()
Ответ на: комментарий от Bohtvaroh

Statement st = connection.createStatement();
ResultSet rs = st.executeQuery("select ID, NAME from PERSON");

while (rs.next()) {
  Person p = new Person(rs.getInteger("id"), rs.getString("name"));
  //
}

Как то так. По-моему вполне естественно.

Legioner ★★★★★
()
Ответ на: комментарий от anonymous

> Открой для себя волшебство курсоров

... которые не поддерживаются необходимым подмножеством СУБД, в некоторых реализациях имею проблемы с производительностью, несовместимы друг с другом и т.д.

Bohtvaroh ★★★★
()
Ответ на: комментарий от Legioner

> Statement st = connection.createStatement(); > ResultSet rs = st.executeQuery("select ID, NAME from PERSON");

> while (rs.next()) { > Person p = new Person(rs.getInteger("id"), rs.getString("name")); > // > }

> Как то так. По-моему вполне естественно.

Это java, а не SQL. ИМХО, это выгребет все записи из таблицы PERSON сразу в executeQuery(...).

Bohtvaroh ★★★★
()
Ответ на: комментарий от kronos_vano

> Хибернейт это костыль для java пытающийся повторить ActiveRecord ?

Нет.

Legioner ★★★★★
()
Ответ на: комментарий от Bohtvaroh

>> Открой для себя волшебство курсоров

>... которые не поддерживаются необходимым подмножеством СУБД

Что, пишем одновременно под SQLite и Oracle? И потому заставляем Оракел быть таким же тупым, как и эскулайт?

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

Ай, ну канешна, ТАКИХ проблем с производительностью, как у приведенного примера нет ни у какой реализации курсоров.

anonymous
()
Ответ на: комментарий от Bohtvaroh

> ИМХО, это выгребет все записи из таблицы PERSON сразу в executeQuery(...).

ИМХО нет :) Потому что select на очень большой результат выполняется очень быстро, если условие нормальное, он банально по сети не успел бы столько передать. По крайней мере на DB2, как на других БД не знаю.

Legioner ★★★★★
()
Ответ на: комментарий от kronos_vano

> Хибернейт это костыль для java пытающийся повторить ActiveRecord ?

Стало интересно, что это за хрень. Погуглил, чуть не умер со смеха. :))

Castle ActiveRecord is built on top of -->>> NHibernate <<<--, but its attribute-based mapping free the developer of writing XML for database-to-object mapping, which is needed when using NHibernate directly.

Для справки, NHibernate - дотнет версия Hibernate.

Bohtvaroh ★★★★
()
Ответ на: комментарий от sv75

>>"В нём реализованы лучшие решения из Java EE, в том числе Spring, Hibernate и SiteMesh."

>Кто из вас двоих ошибается?

сколько криков было по поводу RoR и где он сейчас?
Время покажет :)

Я не сторонник динамических языков.
Если мне чего и не хватает в Java так это Closures и AOP.
Closures обещают в 1.7
AOP - можно брать из Spring, можно AspectJ

Сейчас я бы рекомендовал использовать следующий список технологий:
Hiberate - ORM
GWT - ajax web фреймворк
Spring - JEE framework на базе DI контейнера с подержкрой AOP
Maven - средство автоматизации управление проектом (средством сборки язык не повернулся назвать)
AspectJ - AOP для Java.

я бы не рекомендовал использовать:
JSF - оверинженирнутый фреймворк на котором очень сложно писать ajax приложения (декларативное программирование не подходить для ajax)
EJB (включая JPA) - у них не получилось с третьего раза )
SEAM - фреймворк основанный на JSF и EJB - no comments
Portlets - сдохли, ждем новой спеки.

Yilativs ★★★★
()
Ответ на: комментарий от anonymous

> Что, пишем одновременно под SQLite и Oracle?

А почему бы и нет?

> Ай, ну канешна, ТАКИХ проблем с производительностью, как у приведенного примера нет ни у какой реализации курсоров.

А где проблемы с производительностью? В первом селекте, где получаются все id?

Bohtvaroh ★★★★
()
Ответ на: комментарий от Legioner

> АФАИК ActiveRecord это design pattern

Ну комментатор не уточнил, поэтому интерпретирую как хочу. :)

Bohtvaroh ★★★★
()
Ответ на: комментарий от Yilativs

> Maven - средство автоматизации управление проектом (средством сборки язык не повернулся назвать)

А что он может дать по сравнению с Ant-ом? Я так понял, он умеет внешние библиотеки подгружать. Сейчас все зависимости банально с проектом в svn-е лежат.

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

>Всё, понял почему мне iterate не понравился. Далее предполагаем, что мне надо обработать 20 миллионов записей, причём мне они все сразу не нужны.

для этого нужно использовать
http://www.hibernate.org/hib_docs/reference/en/html/batch.html

иногда можешь обойтись setMaxResult setFirstResult (но очень не советую для таких объёмов данных)
Hibernate Batch твое всё.

Yilativs ★★★★
()
Ответ на: комментарий от Legioner

> А что он может дать по сравнению с Ant-ом?

Я мигрировал на maven пару месяцев назад. При этом избавился от горы хлама в виде ant-скриптов, добился куда большей модульности, unit/integration-тесты запускаются прямо при сборке, получил нормальную поддержку со стороны IDE (eclipse), декларативное управление зависимостями, которые слава хоспаде не лежат в svn, также нормальное управление зависимостями между модулями проекта, универсальную структуру каталогов и т.д.

Bohtvaroh ★★★★
()
Ответ на: комментарий от Bohtvaroh

Заинтересовали :) Погляжу на него. Хотя из описания не совсем понял, чего не умеет Ant. Вроде большинство умеет.

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

>А что он может дать по сравнению с Ant-ом?

(в скобочках будет объяснение по слесарски - долго писать лень, домой хочу, твой пример про hibernate завтра посмотрю)

И так, что дает:

Управление зависимостями.
(решил поменять добавить либу в проект, все либы от которых она зависит сами добавились, решил сменить номер версии используемой либы, все зависимые новые либы подтянулись в проект, старые убрались)

Единая структура и подход для управления проектов.
(приходит новый человек в команду и сразу знает что где лежит)

Легкое написание и поддержка build скрипта
(ты просто пишешь чего хочешь -
хочу тесты, хочу code coverage, ты не описываешь как это будет делаться, просто говоришь какие плагины что будут для тебя делать
Плагины будут собирать,тестировать, создавать репорты,деплоить и все это OUT OF THE BOX, даже сайт твоему проекту сгенерят если надо)


у maven своя документация очень плохая - читай вот эту книжку.
http://www.devzuz.com/web/guest/products/resources#BBWM

Yilativs ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.