You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Some code that was working in 2.5.x is currently not working in 3.3.1. This particular issue is related to GORM and transactions participation (we think). Basically, I have two domain classes where 1 of them (Pipeline) has many of the other (Rule). I have two controllers where I can save a Pipeline first. Then, I call the RuleController to save a rule and add to the pipeline in a Service. However, I want to do some queries to find the Rule after I added it to the pipeline. (Notice this is a simplified example of querying for the Rule on other Pipelines.) However, I noticed that using CreateCriteria, ExecuteQuery, Where, will not get any data unless I flush the save of the pipeline. Is this the right behavior? We used to do this in Grails 2.5.x and it was yielding the data w/o flushing the save.
We are using mySQL as the persistent storage...
Here is the code to replicate the issue
Domain Class
Rule
class Rule {
String name
static constraints = {
}
}
Pipeline
class Pipeline {
String name
static hasMany = [rules: Rule]
static constraints = {
}
}
@Transactional
class PipelineService {
def addToPipeline(params) {
def rule = new Rule(name: params.name)
rule.save()
def ruleID = rule.id
Pipeline pipeline = Pipeline.get(params.pipelineId)
pipeline.addToRules(rule)
// commenting out save is the same as explicit save()
pipeline.save() // this will not allow createCriteria, where, or executeQuery to find pipeline for the just inserted rule
//pipeline.save(flush:true) // this will let all queries work
// this gets the result no matter if we flush or not
def results = Pipeline.list().findAll{rule in it.rules}
// None of the queries below find anything unless save is flushed
//
// withTransactions or withSession still won't find unless flush is set
//Pipeline.withTransaction{
def c = Pipeline.createCriteria()
def results2 = c.list {
rules{
eq("id",ruleID)
}
}
//}
def query = "select distinct p from Pipeline p inner join p.rules rules where rules in (:rule) "
def results3 = []
try{
results3 = Pipeline.executeQuery(query,[rule:rule])
}catch(e){
e.printStackTrace()
}
def results4 = Pipeline.where {
rules.id == ruleID
}.list()
println "results: ${results}"
println "results2: ${results2}"
println "results3: ${results3}"
println "results3: ${results4}"
return rule
}
}
Create a new pipeline by POSTing to /api/pipelines
{"name":"Pipeline1"}
Create a new rule to add to the newly created pipeline (ID 1) by POSTing to /api/rules
{"name":"rule1", "pipelineId":1}
The console should show the pipeline for all results but it is not finding them except for 1 of the queries. If we flush the save for the pipeline, then all queries will find the record in question. See comments in the Service class.
The text was updated successfully, but these errors were encountered:
@graemerocher within same transaction, session, if an object is updated and saved (irrespective whether it is flushed or not) if we query for the same object we should be able to get the dirty instance back. Right?
My understanding:
For get, load within the same transaction: We look at session first, if not found then second level cache if not found then hit DB to retrieve it.
For queries: We hit DB first and retrieve the list and then include/update matching objects from second level cache and then from current session.
I validated this understanding with spring-hibernate(5) project and it looks to be valid.
In fact I tried with grails 3.2.9 - and works there too. But not in grails 3.3.1
Does grails, gorm work differently?
Spring-hiberbnate:
User n = new User();
n.setName(name);
n.setEmail(email);
Session session = sessionFactory.getCurrentSession();
session.save(user);
Criteria c = session.createCriteria(User.class);
c.add(Restrictions.eq("name", user.getName()));
List results = c.list();
System.out.println("Size: " + results.size());
grails-gorm (Works in 3.2.9, but not in 3.3.1):
TestObject o = new TestObject()
o.name = "name_here"
o.description = "desc_here"
o.save()
println "START createCriteria--------------"
def c = TestObject.createCriteria()
def results = c.list {
eq("name", o.name)
}
results?.each {
println it.name + " " + it.description
}
println "END createCriteria--------------"
Some code that was working in 2.5.x is currently not working in 3.3.1. This particular issue is related to GORM and transactions participation (we think). Basically, I have two domain classes where 1 of them (Pipeline) has many of the other (Rule). I have two controllers where I can save a Pipeline first. Then, I call the RuleController to save a rule and add to the pipeline in a Service. However, I want to do some queries to find the Rule after I added it to the pipeline. (Notice this is a simplified example of querying for the Rule on other Pipelines.) However, I noticed that using CreateCriteria, ExecuteQuery, Where, will not get any data unless I flush the save of the pipeline. Is this the right behavior? We used to do this in Grails 2.5.x and it was yielding the data w/o flushing the save.
We are using mySQL as the persistent storage...
Here is the code to replicate the issue
Domain Class
Rule
Pipeline
Controllers
PipelineController
RuleController
Service
PipelineService
UrlMappings
Steps to reproduce:
The text was updated successfully, but these errors were encountered: