Grails 2.1 How Can i add value in join table - grails-2.1

I create 2 tables one Category and one Manufacturer, and There relationship is Many-to-Many,
So i use a join table,
I insert values into two tables individually. Now i want to join two table by their id, but i cannot do, Can you help me....
When i try to insert value in join table give an exception, here is the exception:
Cannot invoke method addToManufacturers() on null object. Stacktrace follows:
java.lang.NullPointerException: Cannot invoke method addToManufacturers() on null object
here is my domain class for Category
static hasMany = [manufacturers: Manufacturer]
static constraints = {
name blank: false, size: 0..60, unique: false
}
static mapping = {
table 't01i001'
id column: 'f_category_id'
name column: 'f_name', length: 30
version column: 'f_revision'
manufacturers joinTable: [name: 't01j001', key: 'k_category_id', column: 'k_manufacturer_id']
}
here is my domain class for manufacturer
static belongsTo = Category
static hasMany = [categories: Category]
static constraints = {
name blank: false, size: 0..60, unique: false
}
static mapping = {
table 't01i002'
id column: 'f_manufacturer_id'
name column: 'f_name', length: 30
version column: 'f_revision'
categories joinTable: [name: 't01j001', key: 'k_manufacturer_id', column: 'k_category_id']
}
add my controller where i try to insert
def manuInsertInCat(){
def message, flag,count=0,categories = []
int catid = params.containsKey("catid") ? params.catid : '0'
int manuid = params.containsKey("manuid") ? params.manuid : '0'
def category = Category.get(catid);
def manufacture = Manufacturer.get(manuid)
category.addToManufacturers(manufacture)
message = "Successfully Loaded"
count++
flag =true
render Category.getJsonData(categories, count, flag, message)
}

At last i complete my job by this process its works fine.
def catInsertInManu(){
def message, flag,count=0,manufacturers = []
String catid = params.containsKey("catid") ? params.catid : '0'
String manuid = params.containsKey("manuid") ? params.manuid : '0'
def category = Category.get(catid)
def manufacture = Manufacturer.get(manuid)
manufacture.addToCategories(category)
def m01i001001s = []
manufacture.categories.each{ cat ->
m01i001001s << [id:cat.id, name:cat.name]
}
manufacturers << [id: manufacture.id, name:manufacture.name, m01i001001s:m01i001001s]
message = "Successfully Loaded"
count++
flag =true
render Manufacturer.getJsonData(manufacturers, count, flag, message)
}

Related

Why I am getting this error? pydantic.error_wrappers.ValidationError: 2 validation errors for DishMenus

model.py
class Dish(db.Entity):
id = PrimaryKey(UUID, auto=True)
dish_name = Required(str, unique =True)
price = Required(float, default=0)
created_at = Required(date)
dish_menus = Set('Dish_Menu')
class Menu(db.Entity):
id = PrimaryKey(UUID, auto=True)
date = Required(date)
dish_menu = Set('Dish_Menu')
class Dish_Menu(db.Entity):
id = PrimaryKey(UUID, auto=True)
dish_availability = Required(int)
dishes = Required("Dish", column = "dish_id")
menus = Required("Menu", column = "menu_id")
routes.py
#api.post('/', status_code=status.HTTP_201_CREATED)
async def create_dish_menu(dish_menu: DishMenus):
with db_session:
new_dish = Dish_Menu(dish_availability = dish_menu.dish_availability,
dishes = dish_menu.dish_id, menus = dish_menu.menu_id)
commit()
result = SaveDishMenu.from_orm(new_dish)
return result
#api.get('/', status_code=status.HTTP_200_OK)
async def get_all_dish_menu():
with db_session:
dish_menu = Dish_Menu.select()
print(dish_menu);
result = [DishMenuDetails.from_orm(i) for i in dish_menu]
return result
schemas.py
class SaveDishMenu(BaseModel):
id : Optional [UUID]
dish_availability: int
class Config:
orm_mode = True
class DishMenus(SaveDishMenu):
dish_id : str
menu_id : str
class Config:
orm_mode = True
class DishMenuDetails(SaveDishMenu):
dish_id : DishDetails
menu_id : MenuSchema
I can post a dish menu, but I have problem in getting all of those input because I'm getting this error: pydantic.error_wrappers.ValidationError: 2 validation errors for DishMenus dish_id field required (type=value_error.missing) menu_id field required (type=value_error.missing)
In my schemas, I inherit some because of some factors. Do I need to change something on my model? or route?
Can someone help me with it? Thanks

Using add or push to add items to an array in groovy

I am getting the following error while push/add items to an array in groovy.
$groovy main.groovy
Caught: groovy.lang.MissingMethodException: No signature of method: [LProgressNotes;.push() is applicable for argument types: (ProgressNotes) values: [ProgressNotes#d35dea7]
Possible solutions: sum(), plus(java.util.Collection), plus([Ljava.lang.Object;), plus(java.lang.Object), use([Ljava.lang.Object;), plus(java.lang.Iterable)
groovy.lang.MissingMethodException: No signature of method: [LProgressNotes;.push() is applicable for argument types: (ProgressNotes) values: [ProgressNotes#d35dea7]
Possible solutions: sum(), plus(java.util.Collection), plus([Ljava.lang.Object;), plus(java.lang.Object), use([Ljava.lang.Object;), plus(java.lang.Iterable)
at main$_buildOutNotes_closure2.doCall(main.groovy:82)
at main.buildOutNotes(main.groovy:75)
at main$buildOutNotes.callCurrent(Unknown Source)
at main.run(main.groovy:64)
Here is the function:
def buildOutNotes(incomingNotes, systemNotes) {
ProgressNotes[] outNotes = systemNotes;
//iterate incoming chares
incomingNotes.each { incoming ->
//split the note further
def iNote = splitIncoming(incoming);
//check that the incoming note is in the system note
def foundNotes = systemNotes.findAll { it.ProgressNote == iNote.ProgressNote }
if(!foundNotes){
//add the incoming note to the outNote
outNotes.push(iNote);
}
}
return outNotes;
}
Here are the articles that show push and add use
https://mrhaki.blogspot.com/2015/01/groovy-goodness-pop-and-push-items-in.html
def list = ['Groovy', 'is', 'great!']
list.push('rocks!')
http://docs.groovy-lang.org/next/html/documentation/working-with-collections.html
def list = [5, 6, 7, 8]
emptyList.add(5)
I am building the example code on https://www.tutorialspoint.com/execute_groovy_online.php.
You can view the example here
http://tpcg.io/NGw4szCv
Here is the full code as well:
//package com.javacodegeeks.groovy.date;
//import static java.util.Calendar.*;
//import groovy.json.*;
//import java.util.Properties;
//import java.util.List;
//progress notes object
class ProgressNotes {
def ActionDate
String ActionBy
String Status
String ProgressNote
ProgressNotes(inActionDate, inActionBy, inStatus, inNote){
this.ActionDate = inActionDate
this.ActionBy = inActionBy
this.Status = inStatus
this.ProgressNote = inNote
}
}
//delimiter
String delimiter = "##";
//out notes
ProgressNotes[] outNotes;
//date patterns
def dateInSystemPattern = "yyyy-MM-dd HH:mm:ss";
def dateIncomingPattern = "MM/dd/yyyy hh:mm ";
/************** SAMPLE DATA START ****************/
//incoming note string
String incomingNote = "2019-12-15T01:29:44 User1: December 13 went to pickup the toilet at the wholesaler " +
"then went to site then remove and replace the toilet then found out that there is a " +
"fruit inside the toilet then clean up the site and silicone around the toilet then " +
"throw the old toilet at dumpster." + delimiter +
"2019-12-13T10:43:05 User2: applied 3 bottles of urinal treatment. let sit for an " +
"hour. augered out urinal main. draining excellent. tried augering toilet. object stuck in " +
"toilet. will not come out. Don will replace." + delimiter +
"2019-12-13T09:18:51 user3: PO 508758 - unclog Washroom " +
"Details: " +
"Unclog toilet bowl and urinal in. Room 116.";
//in system notes
ProgressNotes[] systemNotes = [
["2012-01-26T14:52:50", "User1", "DISPATCHED", "reassign to Space Planning to confirm space availability"],
["2012-02-01T12:23:05", "User2", "DISPATCHED", "spoke to requestor and she has a few relocations and POD requirements."],
["2012-02-01T12:23:45", "User3", "DISPATCHED", "Contacted Customer for clarification spreadsheet is forthcoming for this request."],
["2012-02-03T18:45:00", "User1", "DISPATCHED", "Extending date to allow for clean-up of backlog."]
];
/************** SPLIT incomingNote ****************/
def incomingNotes = [];
if (incomingNote != ""){
incomingNotes = incomingNote.split(delimiter);
}
/************** PICK NOTES ****************/
if (!incomingNotes){
//No incoming notes push the system notes out
outNotes = systemNotes;
}
else{
//check and build the outnotes
outNotes = buildOutNotes(incomingNotes, systemNotes);
}
println("OUTNOTES Length: " + outNotes.length)
println(" ");
/************** HELPER METHODS ****************/
def buildOutNotes(incomingNotes, systemNotes) {
ProgressNotes[] outNotes = systemNotes;
//iterate incoming chares
incomingNotes.each { incoming ->
//split the note further
def iNote = splitIncoming(incoming);
//check that the incoming note is in the system note
def foundNotes = systemNotes.findAll { it.ProgressNote == iNote.ProgressNote }
if(!foundNotes){
//add the incoming note to the outNote
outNotes.push(iNote);
}
}
return outNotes;
}
def splitIncoming(incoming){
//date time characters
int dateTimeChars = 20;
def dateAndTimePart = incoming.substring(0,dateTimeChars).trim();
String remainingNote = incoming.substring(dateTimeChars);
String userPart = "";
String notePart = "";
def remainingNotes = remainingNote.split(":");
if(remainingNotes){
userPart = remainingNotes.getAt(0);
notePart = incoming.substring(dateTimeChars+userPart.length()+1).trim();
}
//build the object
def outNote = new ProgressNotes(dateAndTimePart, userPart, "", notePart);
return outNote;
}
You use an array in your code (ProgressNotes[]), not a list (List<ProgressNotes>). Any of the mentioned methods (add and push) does not exist for Java (and thus Groovy) arrays. An array is fixed size, so once initialized, you can't add any new elements to it - you can only replace existing elements. If you try to add a new element to the array, you will get IndexOutOfBoundsException. Just look at this simple example:
String[] list = ["foo", "bar"]
assert list[0] == "foo"
assert list[1] == "bar"
try {
list[2] = "new"
} catch (IndexOutOfBoundsException e) {
println "Caught!"
}
list[1] = "abc"
println list
Output:
Caught!
[foo, abc]
If you want to use List.add() or List.push() (or event groovier leftShift like [] << "elem") you need to use a list instead of an array. Arrays are a good choice if you know the size of the collection is fixed.
//out notes
List<ProgressNotes> outNotes;

How to Merge two or more Objects in a ObjectsList

I have would like to know if there is a way to merge two ( or more ) objects in one list.
Exemple:
I have this class:
class User {
String name
Integer age
Integer score
}
and I got this method on another class
methodTest() {
User a = new User().with{
it.name = "JACK"
it.age = 20
}
User b = new User().with{
it.name = "JACK"
it.score = 50
}
User c = new User().with{
it.name = "TONY"
it.age = 25
}
User d = new User().with{
it.name = "TONY"
it.score = 30
}
List userList = new ArrayList()
userList.add(a)
userList.add(b)
userList.add(c)
userList.add(d)
}
Tere is a way to get a userList merged by name? Something like :
userList = userList.mergeBy(it.name)
and then get a list of Users with:
[{name:"Jack", age: 20 , score: 50},{name:"TONY", age: 25, score: 30}]
You can use .groupBy to group your list by User.name and then transform it to a List<User> by applying .inject function. Below you can find an example (fixed version the code you have shown us):
import groovy.json.JsonOutput
class User {
String name
Integer age
Integer score
}
User a = new User(name: "JACK", age: 20)
User b = new User(name: "JACK", score: 50)
User c = new User(name: "TONY", age: 25)
User d = new User(name: "TONY", score: 30)
List userList = new ArrayList()
userList.add(a)
userList.add(b)
userList.add(c)
userList.add(d)
List<User> users = userList.groupBy { it.name } // (1)
.values() // (2)
.inject([]) { result, users -> // (3)
result << users.inject(new User()) { User merged, User user -> // (4)
merged.name = user.name ?: merged.name
merged.age = user.age ?: merged.age
merged.score = user.score ?: merged.score
return merged
}
}
println JsonOutput.toJson(users)
Let's see what happens here step-by-step:
(1) userList.groupBy { it.name } produces following map:
[JACK:[User(JACK, 20, null), User(JACK, null, 50)], TONY:[User(TONY, 25, null), User(TONY, null, 30)]]
(2) calling .values() on this map returns a list of list of users:
[[User(JACK, 20, null), User(JACK, null, 50)], [User(TONY, 25, null), User(TONY, null, 30)]]
(3) then .inject([]) { result, users -> /* ... */ } collects every list of users, applies transformation and adds result to result list (we start with empty [] here)
(4) here we call another .inject() function on users list (this users list contains a list of users with same name, e.g. [JACK:[User(JACK, 20, null), User(JACK, null, 50)]). We start with a new "empty" user (.inject(new User())). We access it by merged variable inside the closure - this variable holds the last result of each iteration inside .inject() function. So it starts with this empty user, gets the first one, sets the name and age (score is not set, because it is null), then it gets second user, sets name (same one) and score (age is not set, because in this user has null age). Final User is added to result list using left shift operator <<.
Eventually when you print to console your final users list you will see desired output:
[{"age":20,"score":50,"name":"JACK"},{"age":25,"score":30,"name":"TONY"}]
Final note
Of course you can make this code even simple, e.g. you can add a method to User class that merges two user instances, something like:
import groovy.json.JsonOutput
class User {
String name
Integer age
Integer score
User merge(User user) {
return new User(
name: user.name ?: name,
age: user.age ?: age,
score: user.score ?: score
)
}
}
List<User> userList = [
new User(name: "JACK", age: 20),
new User(name: "JACK", score: 50),
new User(name: "TONY", age: 25),
new User(name: "TONY", score: 30)
]
List<User> users = userList.groupBy { it.name }
.values()
.inject([]) { result, users ->
result << users.inject(new User()) { User merged, User user -> merged.merge(user) }
}
println JsouOutput.toJson(users)
Using some simple groovy magic:
class User{
String name
Integer age
Integer score
String toString(){ "$name:$age:$score" }
}
User a = new User(
name:"JACK",
age : 20
)
User b = new User(
name : "JACK",
score :50
)
User c = new User(
name : "TONY",
age : 25
)
User d = new User(
name : "TONY",
score : 30
)
List userList = [ a, b, c, d ]
def mergedList = userList.inject( [:].withDefault{ new User() } ){ res, User u ->
res[ u.name ].name = u.name
if( u.age ) res[ u.name ].age = u.age
if( u.score ) res[ u.name ].score = u.score
res
}.values()
assert '[JACK:20:50, TONY:25:30]' == mergedList.toString()

groovy.lang.MissingMethodException: No signature of method

I am getting the following error -
groovy.lang.MissingMethodException: No signature of method: Script64$_run_closure5_closure7_closure8_closure9_closure10_closure11.doCall() is applicable for argument types: (java.lang.String) values: Possible solutions: doCall(java.lang.Object, java.lang.Object), isCase(java.lang.Object), isCase(java.lang.Object) error at line:
Code - EDIT
import groovy.xml.*
List tempList = []
List listgenerated = []
def count = 0
for (a in 0..totalCount-1)
{
//nameList and valueList lists will have all the contents added as below commented pseudo code
/*for (b in 0..50)
{
nameList.add(b,number) // number is some calculated value
valueList.add(b,number)
e.g. nameList=[name1, name2, name3,name4, name5]
valueList =[val1, val2, val3, , val5]
listgenerated should be = [[name1:val1, name2:val2], [name3:val3, name4: , name5:val5]]
} */
tempList = []
for (j in count..nameList.size())
{
count = j
def nameKey = nameList[j]
def value
if (nameKey != null)
{
value = valueList[j]
tempList << [(nameKey) : value]
}
}
count = count
listgenerated.putAt(a,tempList)
number = number +1
}
def process = { binding, element, name ->
if( element[ name ] instanceof Collection ) {
element[ name ].each { n ->
binding."$name"( n )
}
}
else if( element[ name ] ) {
binding."$name"( element[ name ] )
}
}
class Form {
List fields
}
def list = [[ name:'a', val:'1' ], [ name:'b', val :'2', name2:4, xyz:'abc', pqr:'']] //Edited list
f = new Form( fields: list ) //Works fine
f = new Form( fields: listgenerated ) //Gives the above error
String xml = XmlUtil.serialize( new StreamingMarkupBuilder().with { builder ->
builder.bind { binding ->
data {
f.fields.each { fields ->
item {
fields.each { name, value ->
process( binding, fields, name )
}
}
}
}
}
} )
If while creating the "listgenerated" single quotes are added around values it takes it as character and while printing both lists seem different.
I am unable to figure it out what exactly is going wrong. Any help is appreciated. Thanks.
Ref - Groovy: dynamically create XML for collection of objects with collections of properties
I believe, where you do:
//some loop to add multiple values to the list
listgenerated << name+":"+value
You need to do:
//some loop to add multiple values to the list
listgenerated << [ (name): value ]
And add a map to the list rather than a String. It's hard to say though as your code example doesn't run without alteration, and I don't know if it's the alterations that are solving the problem

Convert to view model, EF Partial Class calculated property using related entities returns 0

I am using EF 5 and have a new property that I've defined in a partial class to extend the base database fields. It requires summing data from a related table.
[Display(Name = "Qty Allocated")]
public decimal QtyAllocated
{
get { return this.AllocatedContainers == null ? 1 : this.AllocatedContainers.Sum(a => a.AllocatedQty); }
//get { return 2;}
}
This property returns the correct value....BUT, if I then use the following method to convert this to a view model, the returned value is 0. Note the view model inherits from the class:
public class InventoryContainerDetailListViewModel : InventoryContainerDetail
Method:
public IEnumerable<InventoryContainerDetailListViewModel> ConvertClassToViewModel(IEnumerable<InventoryContainerDetail> entityList)
{
IEnumerable<InventoryContainerDetailListViewModel> itemGrid =
from l in entityList.ToList()
select new InventoryContainerDetailListViewModel()
{
Id = l.Id,
InventoryContainerHeaderId = l.InventoryContainerHeaderId,
PONbr = l.ReceiptDetail == null ? (int?)null : l.ReceiptDetail.PODetail.POHeaderId,
ReceiptDetailId = l.ReceiptDetailId,
ItemId = l.ItemId,
ItemDescription = l.Item.ShortDescription,
QtyInContainer = l.QtyInContainer,
//QtyAllocated = l.AllocatedContainers == null ? 0 : l.AllocatedContainers.Sum(a => a.AllocatedQty),
Location = l.InventoryContainerHeader.Location.DisplayLocation
};
return itemGrid;
}
In this method, the input parameter entityList does show each item with the correct calculated values, but after the conversion, the value is always 0.
I assume this has something to do with the fact that I am inheriting from the base class, but can someone shed some light on this?
I don't think that the reason is inheritance. The more probable reason is that AllocatedContainers is empty collection (you don't assign it when creating instance of your view model).

Resources