I'm new to Grails. I'm developing a web app that handles the records of a gymnasium, to make routines, exercises, etc.
I have this domain class Ejercicios:
class Ejercicios {
String nombreEjercicio
String idHoja
String descripcion
List<String> descripcionO
static hasMany = [descripcionO: Descripciones]
static transients = ['descripcionTrans']
String descripcionTrans
static mapping = {
id column: "idHoja"
version false
}
static constraints = {
nombreEjercicio maxSize: 45
idHoja blank: false
}
The database table has the default Grails id named "idHoja", and another attribute named "id_hoja"
The thing here is that when I make a JSON parse from the rest API, I need GORM to look for exercises via the "id_hoja" attribute, not the "idHoja" because it'll cause a mismatch.
I found the solution by myself!
The only thing I needed to was to make the JSON call with the name "idHoja" and that was it.
Related
I've got 3 classes:
class Author {
static hasMany = [books: Book]
static belongsTo = [company: Company]
String name
}
class Book {
static mapping = {
collection "documents"
id generator: 'assigned',index: true, indexAttributes:[background:true, unique:true, dropDups:true]
}
String id
String name
}
class Company {
static mapping = {
collection "documents"
id generator: 'assigned',index: true, indexAttributes:[background:true, unique:true, dropDups:true]
}
String id
String name
}
I want to use
Author author = Author.getByCompanyAndBook(1,1);
but when running this Grails retrieves all the Book objects from the database.
I need those Books only as identifiers for the Author and I am not going to use those objects.
Is there a way for me to force Grails not to fetch the Books and Companies from the database?
I tried to use:
static mapping = {
books lazy: true
}
but still all of the Books and the Company were loaded.
Edit:
I am using mongo db as my database.
That's weird - collections are lazy by default, so getting an author shouldn't retrieve anything in the books collection until you access the books property. But regardless, even if it worked as expected I recommend that you avoid mapped collections. See this talk which shows why collections are unnecessarily expensive and provides workarounds to minimize the costs.
Im trying to 'get my toes wet' with grails, and have decided to make a recipe site as a first project.
Im using grails 2.0.1 and using mongoDB GORM for persistence, which is working fine, and am using static Searchable = true in my models for searching.
Making a simple search utility, I have managed to find recipes by name using:
def recipes = Recipe.withCriteria
{
ilike('name', params.name)
}
The recipes can be found by name. My question is, how can I search the ingredient names to flag as results in the search (regarding the models below)?
Coming from PHP and MySQL, this would be as easy as modifying the query with a join or something
my models are as follows:
class Recipe
{
String name;
String method;
Date dateAdded;
static hasMany = [ingredients:Ingredient];
static Searchable = true;
static constraints =
{
name(blank:false, maxSize: 255)
method(blank:false)
}
static mapping =
{
sort dateAdded: "desc"
}
}
class Ingredient
{
String name;
static hasMany = [recipes:Recipe];
static belongsTo = [Recipe]
static constraints =
{
name blank:false;
}
String toString()
{
return name;
}
}
That should be static searchable = true with a lowercase "s" - see http://grails.org/Searchable+Plugin+-+Mapping
But the Searchable plugin doesn't work with Mongo or other NoSQL datastores. This is because it is implemented using Hibernate events to listen for events corresponding to inserting, deleting, and updating database rows and updating the Lucene index based on those changes. Since there's no Hibernate in the mix, the Searchable isn't aware of any changes.
your .withCriteria search has not much to do with the searchable plugin - it's just a normal SQL search.
Try something like
def recipes = Recipe.withCriteria
{
or {
ilike('name', params.name)
ingredients {
ilike('name', params.name)
}
}
}
in order to search in Recipe and Ingredient names.
see http://grails.org/doc/2.0.x/guide/GORM.html#criteria for more help.
Searchable Plugin works with mongodb but you need to configure and reindex it manually as the default behavior is using hibernate.
change your config.groovy mirrorchanges = false and bulkIndexOnStartup = false
add mapwith attribute to all your domain classes that connects to mongodb.
static mapWith="mongo"
static searchable=true
reindex manually by calling reindex() from bootstrap.groovy and everytime your domain has update events.
def domainList = DomainName.list()
DomainName.reindex(domainList)
this is a helpful link from which i referred to though I did not implement the rabbit mq part as I don't need it at the moment. Hope this helps. http://spring.io/blog/2011/08/29/rabbitmq-enabling-grails-full-text-search-on-cloud-foundry/
I have a small grails service that I created, and I am trying to use the type:'text' on a member of a model. I always see this field come up as a varchar(255) however, even though I have dropped the database and had it recreated.
I essentially have:
class eventParameter{
static belongsTo = [logEvent:LogEvent]
String name
String value
static constraints = {
name blank:false
value blank:false
}
static mapping = {
value type:'text'
}
}
Does anyone have any idea why this does not create the right type of column?
To override the underlying database type, use the sqlType mapping. For example:
static mapping = {
value sqlType:'text'
}
Also, check out the relevant section of the Grails Manual: 5.5.2.10 Custom Hibernate Types
I'm creating a (theoretically) simple hasMany relationship within a domain class. I have two tables with a foreign key relationship between the two. Table 1's domain object is as follows:
Functionality{
String id
static hasMany = [functionalityControllers:FunctionalityController]
static mapping =
{
table 'schema.functionality'
id column:'FUNCTIONALITY_NAME', type:'string', generator:'assigned'
version false
}
}
and domain object 2
FunctionalityController
{
String id
String functionalityName
String controllerName
static mapping =
{
table 'schema.functionality_controller'
id column:'id', type:'string', generator:'assigned'
version:false
}
}
The issue I am having is that when I have the hasMany line inside of the Functionality domain object, the app won't start (both the app and the integration tests). The error is org.springframework.beans.factory.BeanCreationException leading to Invocation of init method failed; nested exception is java.lang.NullPointerException.
Any help would be appreciated.
UPDATE:
*Working Domains*:
class Functionality {
String id
static hasMany = [functionalityConts:FunctionalityCont]
static mapping =
{
table 'schema.functionality'
id column:'FUNCTIONALITY_NAME', type: 'string', generator: 'assigned'
functionalityConts( column:'functionality_name')
version false;
}
}
and
class FunctionalityCont {
String id
String functionalityName
String controllerName
static belongsTo = [functionality: Functionality]
static contraints = {
}
static mapping =
{
table 'schema.functionality_controller'
id column:'id', type: 'string', generator: 'assigned'
functionality(column:'FUNCTIONALITY_NAME')
version false;
}
}
Well 2 things...
1.I'm not sure but I guess that your domain class with the prefix 'Controller' maybe is the responsible, this is because grails is convention over configuration and by convention the controller class ends with Controller prefix and are in the controller folder, in this case is a lil' confusing
2.In GORM and in this case the relationship between objects can be unidirectional or bidirectional, is your decision to choose one, but in both cases there are different implementations, the class Functionality(btw is missing the 'class' word) has the right relationship to FunctionalityController through hasMany, but FunctionalityController doesn't knows about the relationship, so you can implement:
// For unidirectional
static belongsTo = Functionality
// For bidirectional
static belongsTo = [functionality:Functionality]
// Or put an instance of Functionality in your domain class,
// not common, and you manage the relationship
Functionality functionality
So check it out and tell us pls...
Regards
Try adding
static belongsTo = [functionality: Functionality]
to your FunctionalityController class. I suspect there is more to your error than what you've shown, but generally a hasMany needs an owning side to it. Since that is where the foreign key actually lives.
Have been trying to look for an answer for hours, but have so far not managed to come up with an adequate solution, so I'm hoping someone here might have some more experience with Grails, and implementing custom relationships in it.
My problem is that I have two classes:
Company
OrderConfig
OrderConfig contains two references to Company. 1 for a consignee, 1 for a shipper. I implemented the relationship (see below), and everything looks dandy, with my order_config table containing both a consignee_company_id column and a shipper_company_id column.
However, I do not want or need a company_id column at all. I would prefer using the CompanyName as the identifying column. How can I prevent Grails from automatically adding the id column to the company table, and instead use the companyName column as the primary key, thus ensuring my order_config table will be generated containing the companyName and not the company_id?
I tried embedding the company in the orderconfig class, and wrestled with all kinds of other options including the mappings, however I ran into trouble with each and every one of them.
Thanks in advance!
My code so far:
class OrderConfig {
static hasMany = [consignee:Company, shipper:Company]
String toString() {
return "${consignee}"
}
static constraints = {
consignee (blank:false, maxSize:10)
shipper (blank:false, maxSize:10)
}
Company consignee
Company shipper
}
class Company {
String toString() {
return "${companyName}"
}
static constraints = {
companyName(blank:false, maxSize:10)
companyAddress1(blank:false, maxSize:40)
companyAddress2(blank:false, maxSize:40)
companyAddress3(blank:false, maxSize:40)
companyAddress4(blank:false, maxSize:40)
companyZipCode(blank:false, maxSize:36)
companyCountry(blank:false, maxSize:36)
}
String companyName
String companyAddress1
String companyAddress2
String companyAddress3
String companyAddress4
String companyZipCode
String companyCountry
}
You need to look at the advanced GORM config options in the documentation, in section 5.5.2.1
There is an example
class Person {
String firstName
static hasMany = [addresses:Address]
static mapping = {
table 'people'
firstName column:'First_Name'
addresses joinTable:[name:'Person_Addresses', key:'Person_Id', column:'Address_Id']
}
}
there you can see how they are specifying the key and column name on which to do the stuff.
Edit -- I reread your question: if you are asking how to change it so Company has an assigned id, you might be able to do something like this example
static mapping = {
id generator:'assigned', column:'column_name',name:'propertyName'
}
where more options are available here: http://www.grails.org/doc/1.3.x/ref/Database%20Mapping/id.html