|
As a result of complex SQL queries I want to receive "domain view" objects.
These objects shall be populated by grails (hibernate) based on the result of a native sql statement. This means that I need domain objects that are read-only and do not have a representation in the database (i.e. no associated table). The result I want to achieve is quite similar to the "NEW"-operator that can be used in JPA to populate arbitrary classes based on JPQL queries. However I need it in grails with native queries. In grails 1.0.4 I found a solution for my problem (unfortunately the page is german): http://www.ecotronics.ch/webdesign/grails.htm The key is to declare the mapping of the domain class as follows: static mapping = { table 'DUMMY_NAME' version false mutable false } By using "mutable false" you can create a domain object that is never persisted. Unfortunately this does no longer work with grails-1.1. It gives the following error: [main] ERROR cfg.HibernateMappingBuilder - ORM Mapping Invalid: Specified config option [mutable] does not exist for class [EffortView]! Is there a new approach to solve this issue or is this a regression? best regards, Oliver |
|
I can think of several approaches, but I'm not quite sure which will
suit you best - use grail's new domainObject.read() function. It works like get(), but it's for ready-only objects. I'm assuming you already have a view that will return the data you want. - In oracle (not sure about other DBs), you can have a view with an "instead of" trigger on inserts and updates. This could make all your inserts/updates into no-ops. - inject the sessionfactory and use a stateless session SessionFactory sessionFactory; def myAction = { StatelessSession session = null try { session = sessionFactory.openStatelessSession() SQLQuery resultQuery = session.createSQLQuery(queryText) resultQuery.addEntity(MyPseudoEntity.class) return resultQuery.list() } finally { if (session) { session.close() } } } - I released a plugin earlier this week called extended-gorm-mappings that lets you map columns to functions or mark them read-only. While I'd love to see other people use it, it's not really geared to an entire class being read-only -Steve owahlen wrote: > As a result of complex SQL queries I want to receive "domain view" objects. > These objects shall be populated by grails (hibernate) based on the result > of a native sql statement. > This means that I need domain objects that are read-only and do not have a > representation in the database (i.e. no associated table). > > The result I want to achieve is quite similar to the "NEW"-operator that can > be used in JPA to populate arbitrary classes based on JPQL queries. However > I need it in grails with native queries. > > In grails 1.0.4 I found a solution for my problem (unfortunately the page is > german): > http://www.ecotronics.ch/webdesign/grails.htm > > The key is to declare the mapping of the domain class as follows: > static mapping = { > table 'DUMMY_NAME' > version false > mutable false > } > > By using "mutable false" you can create a domain object that is never > persisted. > > Unfortunately this does no longer work with grails-1.1. > It gives the following error: > > [main] ERROR cfg.HibernateMappingBuilder - ORM Mapping Invalid: Specified > config option [mutable] does not exist for class [EffortView]! > > Is there a new approach to solve this issue or is this a regression? > > best regards, > Oliver > > --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
In reply to this post by Oliver Wahlen
On Thu, Mar 12, 2009 at 11:58 PM, owahlen <[hidden email]> wrote:
> > As a result of complex SQL queries I want to receive "domain view" objects. > These objects shall be populated by grails (hibernate) based on the result > of a native sql statement. > This means that I need domain objects that are read-only and do not have a > representation in the database (i.e. no associated table). > > The result I want to achieve is quite similar to the "NEW"-operator that can > be used in JPA to populate arbitrary classes based on JPQL queries. However > I need it in grails with native queries. > > In grails 1.0.4 I found a solution for my problem (unfortunately the page is > german): > http://www.ecotronics.ch/webdesign/grails.htm > > The key is to declare the mapping of the domain class as follows: > static mapping = { > table 'DUMMY_NAME' > version false > mutable false > } > > By using "mutable false" you can create a domain object that is never > persisted. I don't know where that page got that information from but "mutable false" is not something that is or ever has been supported. There was a bug in 1.0.4 where invalid mappings like this wouldn't print errors to the console. So what you're seeing is actually improved error reporting Currently the only way to make an object read-only is to do: static mapping = { cache 'read-only' } Cheers > > Unfortunately this does no longer work with grails-1.1. > It gives the following error: > > [main] ERROR cfg.HibernateMappingBuilder - ORM Mapping Invalid: Specified > config option [mutable] does not exist for class [EffortView]! > > Is there a new approach to solve this issue or is this a regression? > > best regards, > Oliver > > -- > View this message in context: http://www.nabble.com/how-to-NOT-persist-a-domain-class-in-grails-1.1-%28worked-in-1.0.4%21%29-tp22487676p22487676.html > Sent from the grails - user mailing list archive at Nabble.com. > > > --------------------------------------------------------------------- > To unsubscribe from this list, please visit: > > http://xircles.codehaus.org/manage_email > > > -- Graeme Rocher Head of Grails Development SpringSource - Weapons for the War on Java Complexity http://www.springsource.com --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
in the release notes it says the following
Read-Only Access to Objects Persistent instances can now be loaded in a read-only state using the read method: def book = Book.read(1) What is the difference between this and using the mapping you define below? On Mar 13, 2009, at 12:04 PM, Graeme Rocher wrote: > On Thu, Mar 12, 2009 at 11:58 PM, owahlen <[hidden email]> > wrote: >> >> As a result of complex SQL queries I want to receive "domain view" >> objects. >> These objects shall be populated by grails (hibernate) based on the >> result >> of a native sql statement. >> This means that I need domain objects that are read-only and do not >> have a >> representation in the database (i.e. no associated table). >> >> The result I want to achieve is quite similar to the "NEW"-operator >> that can >> be used in JPA to populate arbitrary classes based on JPQL queries. >> However >> I need it in grails with native queries. >> >> In grails 1.0.4 I found a solution for my problem (unfortunately >> the page is >> german): >> http://www.ecotronics.ch/webdesign/grails.htm >> >> The key is to declare the mapping of the domain class as follows: >> static mapping = { >> table 'DUMMY_NAME' >> version false >> mutable false >> } >> >> By using "mutable false" you can create a domain object that is never >> persisted. > > I don't know where that page got that information from but "mutable > false" is not something that is or ever has been supported. There was > a bug in 1.0.4 where invalid mappings like this wouldn't print errors > to the console. So what you're seeing is actually improved error > reporting > > Currently the only way to make an object read-only is to do: > > static mapping = { > cache 'read-only' > } > > Cheers >> >> Unfortunately this does no longer work with grails-1.1. >> It gives the following error: >> >> [main] ERROR cfg.HibernateMappingBuilder - ORM Mapping Invalid: >> Specified >> config option [mutable] does not exist for class [EffortView]! >> >> Is there a new approach to solve this issue or is this a regression? >> >> best regards, >> Oliver >> >> -- >> View this message in context: http://www.nabble.com/how-to-NOT-persist-a-domain-class-in-grails-1.1-%28worked-in-1.0.4%21%29-tp22487676p22487676.html >> Sent from the grails - user mailing list archive at Nabble.com. >> >> >> --------------------------------------------------------------------- >> To unsubscribe from this list, please visit: >> >> http://xircles.codehaus.org/manage_email >> >> >> > > > > -- > Graeme Rocher > Head of Grails Development > SpringSource - Weapons for the War on Java Complexity > http://www.springsource.com > > --------------------------------------------------------------------- > To unsubscribe from this list, please visit: > > http://xircles.codehaus.org/manage_email > > --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
On Fri, Mar 13, 2009 at 5:14 PM, Joshua Burnett <[hidden email]> wrote:
> in the release notes it says the following > Read-Only Access to Objects > Persistent instances can now be loaded in a read-only state using the read > method: > def book = Book.read(1) > > What is the difference between this and using the mapping you define below? If you use cache:'read-only' your object can never be updated after creation.. ever. Whilst with the read method you can still update it if necessary, but use read-only when needed Cheers > > On Mar 13, 2009, at 12:04 PM, Graeme Rocher wrote: > >> On Thu, Mar 12, 2009 at 11:58 PM, owahlen <[hidden email]> wrote: >>> >>> As a result of complex SQL queries I want to receive "domain view" >>> objects. >>> These objects shall be populated by grails (hibernate) based on the >>> result >>> of a native sql statement. >>> This means that I need domain objects that are read-only and do not have >>> a >>> representation in the database (i.e. no associated table). >>> >>> The result I want to achieve is quite similar to the "NEW"-operator that >>> can >>> be used in JPA to populate arbitrary classes based on JPQL queries. >>> However >>> I need it in grails with native queries. >>> >>> In grails 1.0.4 I found a solution for my problem (unfortunately the page >>> is >>> german): >>> http://www.ecotronics.ch/webdesign/grails.htm >>> >>> The key is to declare the mapping of the domain class as follows: >>> static mapping = { >>> table 'DUMMY_NAME' >>> version false >>> mutable false >>> } >>> >>> By using "mutable false" you can create a domain object that is never >>> persisted. >> >> I don't know where that page got that information from but "mutable >> false" is not something that is or ever has been supported. There was >> a bug in 1.0.4 where invalid mappings like this wouldn't print errors >> to the console. So what you're seeing is actually improved error >> reporting >> >> Currently the only way to make an object read-only is to do: >> >> static mapping = { >> cache 'read-only' >> } >> >> Cheers >>> >>> Unfortunately this does no longer work with grails-1.1. >>> It gives the following error: >>> >>> [main] ERROR cfg.HibernateMappingBuilder - ORM Mapping Invalid: >>> Specified >>> config option [mutable] does not exist for class [EffortView]! >>> >>> Is there a new approach to solve this issue or is this a regression? >>> >>> best regards, >>> Oliver >>> >>> -- >>> View this message in context: >>> http://www.nabble.com/how-to-NOT-persist-a-domain-class-in-grails-1.1-%28worked-in-1.0.4%21%29-tp22487676p22487676.html >>> Sent from the grails - user mailing list archive at Nabble.com. >>> >>> >>> --------------------------------------------------------------------- >>> To unsubscribe from this list, please visit: >>> >>> http://xircles.codehaus.org/manage_email >>> >>> >>> >> >> >> >> -- >> Graeme Rocher >> Head of Grails Development >> SpringSource - Weapons for the War on Java Complexity >> http://www.springsource.com >> >> --------------------------------------------------------------------- >> To unsubscribe from this list, please visit: >> >> http://xircles.codehaus.org/manage_email >> >> > > > --------------------------------------------------------------------- > To unsubscribe from this list, please visit: > > http://xircles.codehaus.org/manage_email > > > -- Graeme Rocher Head of Grails Development SpringSource - Weapons for the War on Java Complexity http://www.springsource.com --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
In reply to this post by Steve Shucker
Hello Steve,
the "domainObject.read()" solution and the "cache 'read-only'" mapping both have in common that hibernate tries to create the domain object on the database. The nice thing about the undocumented "mutable false" feature in 1.0.4 was that hibernate did not try to do this. I am not using Oracle but MySql. Furthermore to keep maintainability high I would like to tune the database as little as possible. Therefore this is not a viable solution, either. It seems to me that your sessionFactor injection solution might work. Is it necessary that "MyPseudoEntity" is a domain class? If not in which directory should it be located (maybe src/groovy)? The funny thing is that someone else already had a similar proposal that was postponed from 1.0.1 to 1.2. Have a look here: http://jira.codehaus.org/browse/GRAILS-2515?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel best regards, Oliver
|
|
The example where I injected the SessionFactory doesn't require you to
have a domain class. It's just using autowiring as an easy way to drop down to core hibernate APIs. At this point, you've got a hibernate SQLQuery object that can either return entities or List<Object[]>. Hibernate has a whole chapter on this at http://www.hibernate.org/hib_docs/v3/reference/en-US/html/querysql.html. If you're not using an entity, you should bypass hibernate and inject "dataSource" instead of the session factory and use groovy sql. def sql = Sql.newInstance(dataSource); sql.eachRow(query, [parameterValues]) { row -> //process your row here as if it's a map keyed by column names } -Steve owahlen wrote: > Hello Steve, > the "domainObject.read()" solution and the "cache 'read-only'" mapping both > have in common that hibernate tries to create the domain object on the > database. > The nice thing about the undocumented "mutable false" feature in 1.0.4 was > that hibernate did not try to do this. > I am not using Oracle but MySql. > Furthermore to keep maintainability high I would like to tune the database > as little as possible. > Therefore this is not a viable solution, either. > > It seems to me that your sessionFactor injection solution might work. > Is it necessary that "MyPseudoEntity" is a domain class? > If not in which directory should it be located (maybe src/groovy)? > > The funny thing is that someone else already had a similar proposal that was > postponed from 1.0.1 to 1.2. > Have a look here: > http://jira.codehaus.org/browse/GRAILS-2515?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel > > best regards, > Oliver > > > Steve Shucker wrote: > >> I can think of several approaches, but I'm not quite sure which will >> suit you best >> >> - use grail's new domainObject.read() function. It works like get(), >> but it's for ready-only objects. I'm assuming you already have a view >> that will return the data you want. >> >> - In oracle (not sure about other DBs), you can have a view with an >> "instead of" trigger on inserts and updates. This could make all your >> inserts/updates into no-ops. >> >> - inject the sessionfactory and use a stateless session >> SessionFactory sessionFactory; >> def myAction = { >> StatelessSession session = null >> try { >> session = sessionFactory.openStatelessSession() >> SQLQuery resultQuery = session.createSQLQuery(queryText) >> resultQuery.addEntity(MyPseudoEntity.class) >> return resultQuery.list() >> } finally { >> if (session) { >> session.close() >> } >> } >> } >> >> - I released a plugin earlier this week called extended-gorm-mappings >> that lets you map columns to functions or mark them read-only. While >> I'd love to see other people use it, it's not really geared to an entire >> class being read-only >> >> -Steve >> ... >> >> > > --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
In reply to this post by Oliver Wahlen
Please stop reffering to mutable false as an undocumented feature.
This feature never, ever existed in the first place! Sent from my iPhone On 13 Mar 2009, at 22:41, owahlen <[hidden email]> wrote: > > Hello Steve, > the "domainObject.read()" solution and the "cache 'read-only'" > mapping both > have in common that hibernate tries to create the domain object on the > database. > The nice thing about the undocumented "mutable false" feature in > 1.0.4 was > that hibernate did not try to do this. > I am not using Oracle but MySql. > Furthermore to keep maintainability high I would like to tune the > database > as little as possible. > Therefore this is not a viable solution, either. > > It seems to me that your sessionFactor injection solution might work. > Is it necessary that "MyPseudoEntity" is a domain class? > If not in which directory should it be located (maybe src/groovy)? > > The funny thing is that someone else already had a similar proposal > that was > postponed from 1.0.1 to 1.2. > Have a look here: > http://jira.codehaus.org/browse/GRAILS-2515?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel > > best regards, > Oliver > > > Steve Shucker wrote: >> >> I can think of several approaches, but I'm not quite sure which will >> suit you best >> >> - use grail's new domainObject.read() function. It works like get(), >> but it's for ready-only objects. I'm assuming you already have a >> view >> that will return the data you want. >> >> - In oracle (not sure about other DBs), you can have a view with an >> "instead of" trigger on inserts and updates. This could make all >> your >> inserts/updates into no-ops. >> >> - inject the sessionfactory and use a stateless session >> SessionFactory sessionFactory; >> def myAction = { >> StatelessSession session = null >> try { >> session = sessionFactory.openStatelessSession() >> SQLQuery resultQuery = session.createSQLQuery(queryText) >> resultQuery.addEntity(MyPseudoEntity.class) >> return resultQuery.list() >> } finally { >> if (session) { >> session.close() >> } >> } >> } >> >> - I released a plugin earlier this week called extended-gorm-mappings >> that lets you map columns to functions or mark them read-only. While >> I'd love to see other people use it, it's not really geared to an >> entire >> class being read-only >> >> -Steve >> ... >> > > -- > View this message in context: http://www.nabble.com/how-to-NOT-persist-a-domain-class-in-grails-1.1-%28worked-in-1.0.4%21%29-tp22487676p22506180.html > Sent from the grails - user mailing list archive at Nabble.com. > > > --------------------------------------------------------------------- > To unsubscribe from this list, please visit: > > http://xircles.codehaus.org/manage_email > > --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
Hello Graeme,
I am sorry for being imprecise on this. The problem was finally bypassed by simply removing the "mutable false" and accepting that empty data tables are created on the database level that will never be filled. I wonder why nobody else has run into this issue. Maybe I have a conceptional problem. Therefore I would like to ask the best practice approach to implement the following requirements: Let's say I have two domains A and B with A having a 1:n relationship to B. In a graphical table I want to list all attributes of A joined with all attributes of B (i.e. all attributes shall be visible). The table shall have in place editing for some attributes of B. Thus I want to have a validator for this specific input fields. Below the table there is a save button to persist/update the user inputs to the db. So far my approach was to create a domain class AbView that is the union of the attributes and constraints from A and B: The AbView instances are populated by a highly optimized native sql statement joining A and B on DB level. The AbViews are hereafter used to populate the graphical table and contain constraints to operate the validator. If the user presses "save" the view-domains are analyzed and relevant B objects are updated. Note that it is important to do the join between A and B on DB level since it shall be possible to order by the columns of the graphical table. This is achieved by passing through the clicked column names as order criteria down to the SQL. As you see in this constellation there is no point in creating an AB_VIEW database table. This is why I have used "mutable false" so far. The downside of my approach is the redundancy (copy & paste coding): I have to copy the declarations and constraints from A and B into the AbView class. Is there a better way to achieve the requirements mentioned above? best regards, Oliver
|
|
In reply to this post by Graeme Rocher-3
Hi,
I'm the author of the grails tutorial with "mutable false". I got the idea from hibernate, where there exists a mutable = "false". Graeme Rocher-3 wrote: > I don't know where that page got that information from but "mutable > false" is not something that is or ever has been supported. There was > a bug in 1.0.4 where invalid mappings like this wouldn't print errors > to the console. So what you're seeing is actually improved error > reporting I now corrected my page. Does this mean, that also the annotation mutable=false in an annotated class does not work? How about something like: @Entity (mutable=false) @Table(name="emp") class Employee implements Serializable { And if this is true, is there a list somewhere with the annotations grails supports and the ones that are ignored? Thanks SR |
|
Regardless of its origins - this definetly something that is required in the realworld. I have a similar requirement to Olivers in that I need to execute stored procedures and would like to map these back to a domain class. In this scenario I am using new hibernate generated tables for some data but similarly need to access aggregate data from several legacy tables via a stored procedure. I do not want the domain representation cluttering up my database with empty tables.
Is there any other way to express "mutable false" ? thanks, Keith
|
| Powered by Nabble | Edit this page |
