I have 2 domain classes; the forst of them represents an email address, with the name of the user and the email address itself. The other class represents an email message, with the subject, the sender (one email address) and the recipients (a list of email addresses):
class EmailMessage {
static hasMany = [ to: EmailAddress ]
EmailAddress from
String subject
}
class EmailAddress {
String name
String address
}
But this code doesn't work as I expect:
EmailMessage msg = new EmailMessage()
msg.from = new EmailAddress(name: "User 1", address: "user1#domain.com")
[new EmailAddress(name: "User 2", address: "user2#domain.com"), new EmailAddress(name: "User 3", address: "user3#domain.com")].each {
msg.addToTo(it)
}
msg.subject = "Asunto"
msg.save(failOnError: true)
I get this error:
| Error 2013-08-14 21:08:40,362 [localhost-startStop-1] ERROR util.JDBCExceptionReporter - La columna "FROM_ID" no permite valores nulos (NULL)
NULL not allowed for column "FROM_ID"; SQL statement: insert into email_message (id, version, from_id, subject) values (null, ?, ?, ?) [23502-164]
| Error 2013-08-14 21:08:40,375 [localhost-startStop-1] ERROR context.GrailsContextLoader - Error initializing the application: could not insert: [prueba.EmailMessage];
SQL [insert into email_message (id, version, from_id, subject) values (null, ?, ?, ?)]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not insert: [prueba.EmailMessage]
Message: could not insert: [prueba.EmailMessage]; SQL [insert into email_message (id, version, from_id, subject) values (null, ?, ?, ?)]; constraint [null];
nested exception is org.hibernate.exception.ConstraintViolationException: could not insert: [prueba.EmailMessage]
I don't know if this even can be done, or the cascade save doesn't work as I suppose.
I thik I have tried all combinations of hasMany, belongsTo, etc. in each class, without success.
I have also read this topic but it doesn't work as expected Grails hasOne and hasMany same domain.
Could any one help me? Regards and thanks in advance.
This works for me in the standard memory database
class EmailMessage {
static hasMany = [ to: EmailAddress ]
EmailAddress from
String subject
static mapping = {
from cascade: "save-update" //Pretty sure this is unnecessary
}
}
class EmailAddress {
String name
String address
static belongsTo = EmailMessage
}
Unfortunately you have to save your from before you save the parent.
EmailMessage msg = new EmailMessage()
msg.from = new EmailAddress(name: "User 1", address: "user1#domain.com")
if (!msg.from.save(flush: true)) {
log.error("message could not be saved: " + msg.from.errors)
}
[new EmailAddress(name: "User 2", address: "user2#domain.com"), new EmailAddress(name: "User 3", address: "user3#domain.com")].each {
msg.addToTo(it)
}
msg.subject = "Asunto"
msg.save(failOnError: true)
There is no cascading save in a 1:1 relation.
Related
I have a post request from Angular.
addEmployee(Name: string, Address: string, Salary: number, CreateDate: string) {
const headers = new HttpHeaders().set('content-type', 'application/json');
const employee: EmployeeDataModel = { id: null, name: Name, address: Address, salary: Salary, createdate: CreateDate };
alert(employee);
this.http.post<{data: EmployeeDataModel}>(this.appuri + "api/employee", employee, {headers})
.subscribe((responseData) => {
employee.id = responseData.data.id;
this.employees.push(employee);
this.employeesUpdated.next([...this.employees]);
});
}
I can't read a request body in .net core backend.
[HttpPost]
public async Task<ActionResult<Employee>> AddEmployee([FromBody]Employee employee)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
dbContext.Employees.Add(employee);
await dbContext.SaveChangesAsync();
return CreatedAtAction("GetAllEmployees", new { id = employee.ID }, employee);
}
And i also have this error message in ModelState:
The JSON value could not be converted to System.Int32.
Path: $.id | LineNumber: 0 | BytePositionInLine: 10.
Can you help me please because i don't know what's wrong as i'm new to this.
Remove the id property from your request body, or set it to 0. The value null cannot be parsed to an int by the serializer.
const employee: Partial<EmployeeDataModel> = { name: Name, address: Address, salary: Salary, createdate: CreateDate };
// OR
const employee: EmployeeDataModel = { id: 0, name: Name, address: Address, salary: Salary, createdate: CreateDate };
The Partial<> is only to make sure typescript won't scream at you for ommitting the id property.
Note that setting it to a value other than 0 will mean that your DbContext will try to insert that value into the database, and unless your column in the database is not using IDENTITY (or has IDENTITY INSERT turned on), you will get an error again.
How to write a query for an attribute in the array concept.
Example: fetch the address based on city attribute.
namespace org.sample.basic
participant User identified by userId{
o String userId
o Address[] address optional
}
concept Address {
o String address1
o String address2
o String city
o String state
o Integer zipcode
o String country
o Boolean isAddressValidated default = false
}
given data of:
{ "$class": "org.sample.basic.User", "userId": "id1", "address": [ { $class": "org.sample.basic.Address", "address1": "the-vines", "city": "newyork" }, { $class": "org.sample.basic.Address", "address1": "the-gables", "city": "dallas" } ] } // and so on
your querydef (not posted all fields FYI) would be :
query myquery {
description: "Select all x" statement:
SELECT org.sample.basic.User
WHERE (address CONTAINS (city == "dallas") OR (city == "newyork") )
}
I hope you're using Hyperledger Query Language. Can you try something like this ?
SELECT org.sample.basic.User
WHERE ( address CONTAINS (city== _$city) )
I got an error with grails query.
I had class User:
class User {
String username
String passwordHash
static hasMany = [roles: Role, permissions: String, clients: User, owners: User]
}
When i do query:
def addClient() {
def principal = SecurityUtils.subject?.principal
User currentUser = User.findByUsername(principal);
if (request.method == 'GET') {
User user = new User()
[client: currentUser, clientCount: User.countByOwners(currentUser)]
}
}
Grails say that:
Parameter "#1" is not set; SQL statement: select count(*) as y0_ from user this_ where this_.id=? [90012-164]
Why?
Looks like currentUser is null.
BTW, I wonder, why you count by owners, but specify a user as the owners? According to your hasMany definition, owners is a collection.
I have created an Integration Test in Grails 2.x with the purpouse of testing several controllers in order to simulate a complete user flow within a Web App.
First I saved two simple domain object records, instantiating two controller instances within my test case. This two simple classes are:
- Category (category of a product) and
- Store (mini market where products are sale)
I wrote two testing methods to control the controller instances (StoreController and CategoryController) and worked fine, one category record was created and several store records as well.
Then, I wrote a third method to try to save a Product record. This record must reference a Category. So, I take the category instance from previous methods and try to pass it to the ProductController among the other Product parameters.
For an unknown reason, I'm only able to create Product records through the web app instance typing the data in the web browsers, but not by the test class code.
I think the problem issue is with the relationship between Product and Category, but I could not figured out how I should pass the parameters to the ProductController from my test case in order to create a new Product record.
This is my Product class:
class Product {
int id
String barCode
String shortDesc
String longDesc
String format
Category category
static belongsTo = [category: Category]
//static hasManySurveyRecord = [surveyRecord: SurveyRecord]
static constraints = {
id editable: false
barCode blank: false, nullable: false, maxSize: 64
shortDesc blank: false, nullable: false, maxSize: 32
longDesc blank: false, nullable: false, maxSize: 128
category blank: false
}
static mapping = {
table 'product_catalog'
version false
columns {
id column: 'id'
barCode column: 'bar_code'
shorDesc column: 'short_desc'
longDesc column: 'long_desc'
format column: 'format'
}
}
String toString() {
return longDesc
}
}
This is my Category class:
class Category {
int id
String description
static hasManyProduct = [products: Product]
static constraints = {
id editable: false
description blank: false, nullable: false, maxSize: 64
}
static mapping = {
table 'categories'
version false
columns {
id column: 'id'
description column: 'description'
}
}
String toString() {
return description
}
}
This is my integration test for this app:
static transactional = false
static storeList = []
static storesData = []
static categoryIns
static categoryData = []
static productIns = new Product()
static productData = []
#Before
void setup() {
storesData.add([zipCode: 926260001, address: "first test avenue, first city, CA" , description: "first testing store"])
storesData.add([zipCode: 926260002, address: "second test avenue, second city, CA" , description: "second testing store"])
storesData.add([zipCode: 926260003, address: "third test avenue, third city, CA" , description: "third testing store"])
storesData.add([zipCode: 926260004, address: "fourth test avenue, fourth city, CA" , description: "fourth testing store"])
storesData.add([zipCode: 926260005, address: "fifth test avenue, fifth city, CA" , description: "fifth testing store"])
storesData.add([zipCode: 926260006, address: "sixth test avenue, sixth city, CA" , description: "sixth testing store"])
storesData.add([zipCode: 926260007, address: "seventh test avenue, seventh city, CA", description: "seventh testing store"])
storesData.add([zipCode: 926260008, address: "eighth test avenue, eighth city, CA" , description: "eighth testing store"])
categoryData = [description: "testing category"]
productData = [barCode: "0114B", shorDesc: "The short testing description", longDesc: "The long testing description ....", format: "1 LT"]
}
#Test
void _01__createStores() {
def storeCtl = new StoreController()
(0..7).each { i ->
def model = storeCtl.create()
assert model.storeInstance != null
storeCtl.response.reset()
storeCtl.params.putAll( storesData.get(i) )
storeCtl.save()
assert Store.count() == (i+1)
}
storeList.addAll( Store.list() )
assert storeList.size() == Store.list().size()
}
#Test
void _02__createCategory() {
// Test if there is a previous store list created
assert storeList.size() == Store.list().size()
def categoryCtl = new CategoryController()
def model = categoryCtl.create()
assert model.categoryInstance != null
categoryCtl.response.reset()
categoryCtl.params.putAll( categoryData )
categoryCtl.save()
assert Category.count() == 1
categoryIns = Category.list()[0]
}
#Test
void _03__createProduct() {
// Test if there is a previous store list created
assert storeList.size() == Store.list().size()
// Test if there is a previous category created
assert categoryIns != null
assert categoryIns.id > 0
def productCtl = new ProductController()
def model = productCtl.create()
assert model.productInstance != null
productCtl.response.reset()
productData.put("category", [id: categoryIns.id])
productData.put("category.id", categoryIns.id)
productCtl.params.putAll( productData )
//productCtl.params.category = Category.get(categoryIns.id)
productCtl.save()
assert Product.count() == 1
}
This is my ProductController code extract:
def save() {
def productInstance = new Product(params)
if (!productInstance.save(flush: true)) {
render(view: "create", model: [productInstance: productInstance])
return
}
flash.message = message(code: 'default.created.message', args: [message(code: 'product.label', default: 'Product'), productInstance.id])
redirect(action: "show", id: productInstance.id)
}
Both recomendations worked fine. After hours and hours trying to figure out what were going wrong, thanks to you I saw clear my silly silly mistake: a field "shortDesc" was misspelled as "shorDesc".
So, one little tip to my book has been written.
Thank you very much!
I have the following model:
the i run the following to add a new user:
using (var context = new CamelotDB())
{
Console.WriteLine("Creating Test User");
DomainEntity userToAdd = new DomainEntity()
{
EntityName = "Test User",
EntityType = DomainEntity.eEntityType.User,
EntityCreationDate = DateTime.Now,
EntityLastUpdateDate = DateTime.Now,
EntityCreatorUserID = 0,
Creator = context.DomainEntities.Find(0),
EntityUpdaterUserID = 0,
Updater = context.DomainEntities.Find(0),
EntityParentID = null,
UserDetails = new User()
{
Username = "TestUser",
Password = "123",
Email = "TestUser#Test.org",
FirstName = "Test",
LastName = "User",
Phone = "123456789"
}
};
Console.WriteLine("Adding user to Database...");
userToAdd = context.DomainEntities.Add(userToAdd);
context.SaveChanges();
}
And I get the following error:
Multiplicity constraint violated. The role 'User' of the relationship 'CamelotShiftManagement.DAL.DomainEnttyFK1' has multiplicity 1 or 0..1.![enter image description here]
The problem was not the user entity referenced by the Domain Entity.
The problem is the self references for the creator and updater.
they are both not Nullable ... so i had to add an actual ID number to the properties and that required to place an actual User entity in the Navigation Properties of Creator and Updater.