How to delete a child domain row in grails - oracle

I am saving data to my entry meeting table as well as entry meeting details table which is a child table of entry meeting table. But When I want to delete only a child table record it's giving a error. I can't understand what to do. I am using grails 2.1.0. Can anyone please help me on this please ?!!! Here is my code below :
my parent domain >>>
class AdtEntryMeeting {
static mapping = {
table('ADT_ENTRY_MEETING')
version(false)
entryMeetingDetails cascade: 'all'
}
String meetingVenue
Date meetingDate = new Date()
String meetingTime
long CREATED_BY=0
Date CREATED_DATE=new Date()
long UPDATED_BY=0
Date UPDATED_DATE=new Date()
static hasMany = [entryMeetingDetails: AdtEntryMeetingDetails]
static constraints = {
meetingVenue(nullable: false, blank: false)
meetingDate(nullable: false)
meetingTime(nullable: false, blank: false)
CREATED_BY(nullable:true)
CREATED_DATE(nullable:true)
UPDATED_BY(nullable: true)
UPDATED_DATE(nullable: true)
}
String toString(){
return id
}
}
my child domain >>>
class AdtEntryMeetingDetails {
static mapping = {
table('ADT_ENTRY_MEETING_DETAILS')
version(false)
}
AuditFirm auditPack
AuditorDtl auditor
String meetingSubject
String responsiblePerson
AdtEntryMeeting entryMeeting
static constraints = {
auditPack(nullable: false, blank: false)
auditor(nullable: false, blank: false)
meetingSubject(nullable: false, blank: false)
responsiblePerson(nullable: false, blank: false)
entryMeeting(nullable: false, blank: false)
}
String toString(){
return auditPack
}
}
my action to delete >>>
if(params[isDelete + detailsCounter] == 'delete'){
def entryMeetingDetailsDelete = AdtEntryMeetingDetails.get(Long.parseLong(params[entryMeetingDetailsId + detailsCounter]))
entryMeetingDetailsDelete.delete()
}else{
def entryMeetingDetailsEdit = AdtEntryMeetingDetails.get(Long.parseLong(params[entryMeetingDetailsId + detailsCounter]))
entryMeetingDetailsEdit.properties['auditPack'] = AuditFirm.get(Long.parseLong(params[auditPack + detailsCounter]))
entryMeetingDetailsEdit.properties['auditor'] = AuditorDtl.get(Long.parseLong(params[auditor + detailsCounter]))
entryMeetingDetailsEdit.properties['meetingSubject'] = params[meetingSubject + detailsCounter]
entryMeetingDetailsEdit.properties['responsiblePerson'] = params[responsiblePerson + detailsCounter]
adtEntryMeetingInstance.addToEntryMeetingDetails(entryMeetingDetailsEdit)
}
the error I am getting >>>
deleted object would be re-saved by cascade (remove deleted object from associations)

You should first remove the reference from parent and then delete the child
e.g
def entryMeetingDetailsDelete = AdtEntryMeetingDetails.get(Long.parseLong(params[entryMeetingDetailsId + detailsCounter]))
adtEntryMeetingInstance.removeFromAdtEntryMeetingDetails(entryMeetingDetailsDelete)
entryMeetingDetailsDelete.delete()

Related

Exceptions not captured in opencsv parsing

I'm trying to parse a csv file and map it onto a data class. I've setup some validations for the columns and I'm testing it by sending incorrect values for those columns. opencsv throws a generic exception
Basic instantiation of the given bean type (and subordinate beans created through recursion, if applicable) was determined to be impossible.
Code details
Data class:
data class UserInfo(
#CsvBindByName(column = "Id", required = true) val id: Long,
#CsvBindByName(column = "FirstName", required = true) val firstName: String,
#CsvBindByName(column = "LastName", required = true) val lastName: String,
#CsvBindByName(column = "Email", required = true) val email: String,
#CsvBindByName(column = "PhoneNumber", required = true) val phoneNumber: String,
#PreAssignmentValidator(
validator = MustMatchRegexExpression::class, paramString = "^[0-9]{10}$")
#CsvBindByName(column = "Age", required = true)
val age: Int
)
csv parsing logic
fun uploadCsvFile(file: MultipartFile): List<UserInfo> {
throwIfFileEmpty(file)
var fileReader: BufferedReader? = null
try {
fileReader = BufferedReader(InputStreamReader(file.inputStream))
val csvToBean = createCSVToBean(fileReader)
val mappingStrategy: HeaderColumnNameMappingStrategy<Any> =
HeaderColumnNameMappingStrategy<Any>()
mappingStrategy.type = UserInfo::class.java
val userInfos = csvToBean.parse()
userInfos.stream().forEach { user -> println("Parsed data:$user") }
csvToBean.capturedExceptions.stream().forEach { ex -> println(ex.message) }
return userInfos
} catch (ex: Exception) {
throw CsvImportException("Error during csv import")
} finally {
closeFileReader(fileReader)
}
}
private fun createCSVToBean(fileReader: BufferedReader?): CsvToBean<UserInfo> =
CsvToBeanBuilder<UserInfo>(fileReader)
.withType(UserInfo::class.java)
.withThrowExceptions(false)
.withIgnoreLeadingWhiteSpace(true)
.build()
I'm looking for the proper error message for the validation / missing field so that I can communicate it to the error response.

Filter inside MemberProperties return error : Expected type mismatch: inferred type is KProperty1<out Any!, Any?>? but KProperty1<T, *>? was expected

I'm trying to create a inline function that can return entity column name, but get error when i try to filter list of memberProperties from a instance class that i create
This is the error i get :
Expected type mismatch: inferred type is KProperty1<out Any!, Any?>? but KProperty1<T, *>? was expected
i try the tutorial from this Create a class instance using a string containing the package name and class name
Here is my entity:
#Entity
#Table(name = "employee", schema = "dbo")
data class Employee(
#Id
#Column(name = "id", nullable = false, length = 20)
var id: String,
#Column(name = "employee_name", nullable = true, length = 30)
var employeeName: String? = "",
#ManyToOne
#JoinColumn(name = "dept_code", referencedColumnName = "dept_code", nullable = true)
var dept: MasterDept? = null
)
#Entity
#Table(name = "ms_dept", schema = "dbo")
data class MasterDept(
#Id
#Column(name = "dept_code", nullable = false, length = 20)
var code: String,
#Column(name = "dept_desc", nullable = true, length = 100)
var desc: String? = "",
#ManyToOne
#JoinColumn(name = "div_code", referencedColumnName = "div_code", nullable = true)
var div: MasterDiv? = null
)
#Entity
#Table(name = "ms_div", schema = "dbo")
data class MasterDiv(
#Id
#Column(name = "div_code", nullable = false, length = 20)
var code: String,
#Column(name = "div_desc", nullable = true, length = 100)
var desc: String? = ""
)
i try to get column name from property desc of entity MasterDept or MasterDiv, depend of usage
here is my function :
inline fun <reified T : Any> getColumnName(filt:String):String {
var listFilter:List<String> = listOf();
if(filt.contains(".", true)){
listFilter = filt.split(".")
filt = listFilter.get(0)
}
var property = T::class.memberProperties.filter { prop -> prop.name == filt}.firstOrNull()//here is working
var colName : String = ""
var tableName:String = ""
if(listFilter.size > 1){
var idx:Int = 1
for(item : String in listFilter) {
if(idx < listFilter.size){
val cls = Class.forName(property!!.returnType.toString()).kotlin
var table = cls.annotations.find { it.annotationClass == Table::class } as? Table
tableName = table!!.name
property = cls.memberProperties.filter { prop -> prop.name == listFilter.get(idx)}.firstOrNull() //error in here
}
idx++
}
}
var field = property!!.javaField!!
var column = field.getAnnotation(Column::class.java)
return tableName + "." + column!!.name()
}
filt parameter sometimes is "employeeName", "dept.desc" or "dept.div.desc"
am i missing something??
I would be glad for any help.
Kotlin is a strongly typed language. You can't declare a variable with a type KProperty1<T, *>? and reassign it with a value of type KProperty1<out Any, *>? (because the latter is not a subtype of the former). Actually, you haven't declared these types explicitly; they were inferred by the compiler.
Not sure what's going on in this code (and if it is possible to avoid mutation of the property variable, which is preferrable), but you can fix this error by declaring property's type as KProperty1<*, *>?, which is a supertype of all other KProperty1 types; also its declaration could be simplified:
var property: KProperty1<*, *>? = T::class.memberProperties.firstOrNull { it.name == filt }

Kotlin iterator to check if payload list have an id/projectId or not, returning false when there is no attributes?

I have an issue where i have a method where i am checking the payload has the attributes or not. When i am sending my payload i want to check that the user dont have inserted attributes which not allowed in the payload.
My entity class:
#Entity
data class ProjectAssociated(
#Id
#GeneratedValue(generator = "uuid2")
#GenericGenerator(name = "uuid2", strategy = "uuid2")
#Column(columnDefinition = "BINARY(16)")
var id: UUID? = null,
#Column(columnDefinition = "BINARY(16)")
var projectId: UUID? = null,
#Column(columnDefinition = "BINARY(16)")
var associatedProjectId: UUID? = null
)
My Service class:
fun addAssociatedProjectByProjectId(
projectId: UUID,
projectAssociatedList: MutableList<ProjectAssociated>
): MutableList<ProjectAssociated> {
if (projectAssociatedList.isNotEmpty()) {
println(projectAssociatedList)
if (!projectAssociatedList.map { it.id }.isNullOrEmpty()) {
val errorMessage = "Not allowed to provide parameter 'id' in this request"
throw UserInputValidationException(errorMessage)
}
if (!projectAssociatedList.map { it.projectId }.isNullOrEmpty()) {
val errorMessage = "Not allowed to provide parameter 'projectId' in this request"
throw UserInputValidationException(errorMessage)
}
val checkIds = projectAssociatedList.map {
projectRepository.existsById(it.associatedProjectId)
}
if (checkIds.contains(false)) {
val errorMessage = "One or more ID 'associatedProjectId' not exists"
throw UserInputValidationException(errorMessage)
}
}
return projectAssociatedList.map {
projectAssociatedRepository.save(
ProjectAssociated(
null,
projectId,
it.associatedProjectId
)
)
}.toMutableList()
}
My Controller class:
#ApiOperation("Add associated Projects to a specific Project")
#PostMapping(path = ["/project-associated"], consumes = [MediaType.APPLICATION_JSON_VALUE])
fun createAssociatedProjectList(
#ApiParam("The id of the Project", required = true)
#RequestParam("id")
id: UUID,
#ApiParam("JSON object representing the ProjectAssociated")
#RequestBody projectAssociated: MutableList<ProjectAssociated>
): ResponseEntity<WrappedResponse<MutableList<ProjectAssociated>>> {
val createdProjectAssociatedList = projectService.addAssociatedProjectByProjectId(id, projectAssociated)
return ResponseEntity
.status(201)
.location(URI.create("$id/project-associated"))
.body(
ResponseDto(
code = 201,
data = PageDto(list = mutableListOf(createdProjectAssociatedList))
).validated()
)
}
But when i try to send this payload with the project id in #RequestParam:
[
{
"associatedProjectId": "7fe40f90-5178-11ea-9136-1b65a920a5d9"
},
{
"associatedProjectId": "7fe8aaaa-5178-11ea-9136-1b65a920a5d9"
}
]
I have a custom exception where i tell the user if projectId or the id is in the payload that is now allowed to have it in the payload. When i try to POST the payload example above it tells me that projectId or id is in the request? How can that be?
I also printed out the list before if checks:
[ProjectAssociated(id=null, projectId=null, associatedProjectId=7fe40f90-5178-11ea-9136-1b65a920a5d9), ProjectAssociated(id=null, projectId=null, associatedProjectId=7fe8aaaa-5178-11ea-9136-1b65a920a5d9)]
What am I doing wrong?
Thanks for the help!
In the block projectAssociatedList.map { it.id } you are mapping your list to something like [null, null] and it is not null or empty.
So, the complete condition !projectAssociatedList.map { it.id }.isNullOrEmpty() returns true.
If you want to continue using the same logic, you should use !projectAssociatedList.mapNotNull { it.id }.isNullOrEmpty() instead.
The mapNotNull function will filter the null values and output a list just with the not null values. If there is only null values, the list will be empty.
But, a simpler and expressive way to check if there is any not null attribute in a list of objects could be projectAssociatedList.any { it.id != null }

Saving of grails domain object with an attribute type object fails

I'm trying to save a domain object with grails 2.3.3 But it is not saved. How can I save it and why is it not saving?
The domain code:
package berg
import nl.jappieklooster.Log
class FieldValue {
Object value
public String toString(){
Log.debug "Field value: {0}", value
return value.toString()
}
static constraints = {
}
}
The code that saves:
// an extract from the bootsrap file
def init = { servletContext ->
def blueFV = new FieldValue(value: Color.blue)
def smallFV = new FieldValue(value: "small")
def fieldVals = [blueFV, smallFV]
saveData(fieldVals,berg.FieldValue)
}
public void saveData(List list, Class type){
def wholeList = type.list() ?: []
println("Started with adding the "+type.getName()+" classes.")
int saved = 0;
int failed = 0;
if(!wholeList){
list.each{ i ->
if(i.validate()){
i.save(flush:true, failOnError: true)
saved++
}
else{
println("! - - - Warning: '"+i.toString()+"' could not be created! - - - !")
failed++
}
}
if(failed > 0)//if one fails, let the message appear more clearly
println(".v.v.")
println("When saving the "+type.getName()+" classes: "+saved+" were saved, "+failed+" failed to be saved.")
if(failed > 0)
println(".^.^.")
}
}
The entire value column does not show up in the database

MVC3 ajaxgrid scaffolding error, Cannot implicitly convert type 'System.Linq.IQueryable' to 'System.Data.Objects.ObjectQuery'

I'm using MVC3 ajaxgrid scaffolding with EF4.1 code first and i've this error:
Cannot implicitly convert type 'System.Linq.IQueryable' to 'System.Data.Objects.ObjectQuery'
The code with the error in, is autogenerated:
public ActionResult GridData(int start = 0, int itemsPerPage = 20, string orderBy = "UserID", bool desc = false)
{
Response.AppendHeader("X-Total-Row-Count", repository.Users.Count().ToString());
ObjectQuery<User> users = (repository as IObjectContextAdapter).ObjectContext.CreateObjectSet<User>();
users = repository.Users.Include(u => u.Role); //ERROR HERE
users = users.OrderBy("it." + orderBy + (desc ? " desc" : ""));
return PartialView(users.Skip(start).Take(itemsPerPage));
}
This is the Users repository method and the Roles Foreign Key
public IQueryable<Entities.User> Users
{
get { return context.Users; }
}
public IQueryable<Entities.Role>Roles
{
get { return context.Roles; }
}
How can i resolve the conversion?
Get rid of the Lambda and use the related object:
var users = repository.Users.Include("Role"); //ERROR HERE
Assuming the entity User has a navigational property Role.
The reason is clear:
You have users variable with ObjectQuery<User> type then you assign that variable result of a query which is IQueryable<User>.
UPDATE:
Try the code below:
public ActionResult GridData(int start = 0, int itemsPerPage = 20, string orderBy = "UserID", bool desc = false)
{
Response.AppendHeader("X-Total-Row-Count", repository.Users.Count().ToString());
//ObjectQuery<User> users = (repository as IObjectContextAdapter).ObjectContext.CreateObjectSet<User>();
var users = repository.Users.Include(u => u.Role); //ERROR HERE
users = users.OrderBy("it." + orderBy + (desc ? " desc" : ""));
return PartialView(users.Skip(start).Take(itemsPerPage));
}

Resources