I tried last week get values ??from a lazy child of one domain in gsp, but i dont know how i can do this with multi-tenant application. When the application have default datasource this problem does not happen, but when i change the application to multi-tenant this problem appers.
Someone know how i can get the values ??from lazy child in gsp?
DOMAINS
import grails.gorm.MultiTenant;
class Pessoa implements MultiTenant<Pessoa>{
String nome
Endereco endereco
static constraints = {
nome(nullable:false);
endereco(nullable:true);
}
static mapping = {
enderecos cascade:"all-delete-orphan"
}
}
import grails.gorm.MultiTenant;
class Endereco implements MultiTenant<Endereco> {
String rua;
Integer numero;
static constraints = {
rua(nullable:false);
numero(nullable:false);
}
}
CONTROLLER
package project_multitenancy
import grails.validation.ValidationException
import static org.springframework.http.HttpStatus.*
import grails.gorm.multitenancy.*
@CurrentTenant
class PessoaController {
static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]
def index(Integer max) {
params.max = Math.min(max ?: 10, 100)
[pessoaList: Pessoa.list(), pessoaCount: Pessoa.count()]
}
def show(Long id) {
[pessoa: Pessoa.get(id)]
}
def create() {
params.enderecos = [new Endereco()]
[pessoa: new Pessoa(params)]
}
def save() {
def pessoa = new Pessoa(params)
try {
pessoa.save(flush: true)
} catch (ValidationException e) {
respond pessoa.errors, view:'create'
return
}
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.created.message', args: [message(code: 'pessoa.label', default: 'Pessoa'), pessoa.id])
redirect pessoa
}
'*' { respond pessoa, [status: CREATED] }
}
}
def edit(Long id) {
def pessoa = Pessoa.get(id)
println pessoa
[pessoa: pessoa]
}
def update(Long id) {
def pessoa = Pessoa.get(id)
try {
pessoa.save(flush: true)
} catch (ValidationException e) {
respond pessoa.errors, view:'edit'
return
}
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.updated.message', args: [message(code: 'pessoa.label', default: 'Pessoa'), pessoa.id])
redirect pessoa
}
'*'{ respond pessoa, [status: OK] }
}
}
def delete(Long id) {
def pessoa = Pessoa.get(id)
unidadeInstance.delete(flush: true)
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.deleted.message', args: [message(code: 'pessoa.label', default: 'Pessoa'), id])
redirect action:"index", method:"GET"
}
'*'{ render status: NO_CONTENT }
}
}
}
GSP Example
<!DOCTYPE html>
<html>
<head>
<meta name="layout" content="main" />
<g:set var="entityName" value="${message(code: 'pessoa.label', default: 'Pessoa')}" />
<title><g:message code="default.show.label" args="[entityName]" /></title>
</head>
<body>
<a href="#show-pessoa" class="skip" tabindex="-1"><g:message code="default.link.skip.label" default="Skip to content…"/></a>
<div class="nav" role="navigation">
<ul>
<li><a class="home" href="${createLink(uri: '/')}"><g:message code="default.home.label"/></a></li>
<li><g:link class="list" action="index"><g:message code="default.list.label" args="[entityName]" /></g:link></li>
<li><g:link class="create" action="create"><g:message code="default.new.label" args="[entityName]" /></g:link></li>
</ul>
</div>
<div id="show-pessoa" class="content scaffold-show" role="main">
<h1><g:message code="default.show.label" args="[entityName]" /></h1>
<g:if test="${flash.message}">
<div class="message" role="status">${flash.message}</div>
</g:if>
<fieldset class="form">
<div class="fieldcontain">
<label for="nome">Nome
</label>
${this.pessoa.nome}
</div>
<div class="fieldcontain">
<label for="nome">Endereco
</label>
${this.pessoa.endereco.rua}
</div>
</fieldset>
<g:form resource="${this.pessoa}" method="DELETE">
<fieldset class="buttons">
<g:link class="edit" action="edit" resource="${this.pessoa}"><g:message code="default.button.edit.label" default="Edit" /></g:link>
<input class="delete" type="submit" value="${message(code: 'default.button.delete.label', default: 'Delete')}" onclick="return confirm('${message(code: 'default.button.delete.confirm.message', default: 'Are you sure?')}');" />
</fieldset>
</g:form>
</div>
</body>
</html>
When I try get values from ${this.pessoa.endereco.rua} the exception apears:
2020-12-21 15:20:30.353 ERROR --- [io-8080-exec-10] .a.c.c.C.[.[.[.[grailsDispatcherServlet] : Servlet.service() for servlet [grailsDispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.grails.gsp.GroovyPagesException: Error evaluating expression [this.pessoa.endereco] on line [32]: could not initialize proxy - no Session] with root cause
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:147)
at org.grails.orm.hibernate.proxy.SimpleHibernateProxyHandler.unwrapProxy(SimpleHibernateProxyHandler.java:88)
at org.grails.orm.hibernate.cfg.GrailsHibernateUtil.unwrapProxy(GrailsHibernateUtil.java:386)
at org.grails.orm.hibernate.cfg.HibernateUtils$_handleLazyProxy_closure3.doCall(HibernateUtils.groovy:124)
at C__Users_craw02_Documents_GitHub_multitenancy_grails_app_views_pessoa_show_gsp$_run_closure2$_closure26.doCall(C__Users_craw02_Documents_GitHub_multitenancy_grails_app_views_pessoa_show_gsp:61)
at org.grails.gsp.GroovyPage.evaluate(GroovyPage.java:253)
at C__Users_craw02_Documents_GitHub_multitenancy_grails_app_views_pessoa_show_gsp$_run_closure2.doCall(C__Users_craw02_Documents_GitHub_multitenancy_grails_app_views_pessoa_show_gsp:61)
at org.grails.taglib.TagBodyClosure.executeClosure(TagBodyClosure.java:200)
at org.grails.taglib.TagBodyClosure.captureClosureOutput(TagBodyClosure.java:102)
at org.grails.taglib.TagBodyClosure.call(TagBodyClosure.java:213)
at org.grails.plugins.web.taglib.SitemeshTagLib.captureTagContent(SitemeshTagLib.groovy:48)
at org.grails.plugins.web.taglib.SitemeshTagLib$_closure3.doCall(SitemeshTagLib.groovy:156)
at org.grails.gsp.GroovyPage.invokeTagLibClosure(GroovyPage.java:446)
at org.grails.gsp.GroovyPage.invokeTag(GroovyPage.java:364)
at C__Users_craw02_Documents_GitHub_multitenancy_grails_app_views_pessoa_show_gsp.run(C__Users_craw02_Documents_GitHub_multitenancy_grails_app_views_pessoa_show_gsp:78)
at org.grails.gsp.GroovyPageWritable.doWriteTo(GroovyPageWritable.java:162)
at org.grails.gsp.GroovyPageWritable.writeTo(GroovyPageWritable.java:82)
at org.grails.web.servlet.view.GroovyPageView.renderTemplate(GroovyPageView.java:76)
at org.grails.web.servlet.view.AbstractGrailsView.renderWithinGrailsWebRequest(AbstractGrailsView.java:71)
at org.grails.web.servlet.view.AbstractGrailsView.renderMergedOutputModel(AbstractGrailsView.java:55)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:304)
at org.grails.web.sitemesh.GrailsLayoutView.renderInnerView(GrailsLayoutView.java:150)
at org.grails.web.sitemesh.GrailsLayoutView.obtainContent(GrailsLayoutView.java:128)
at org.grails.web.sitemesh.GrailsLayoutView.renderTemplate(GrailsLayoutView.java:63)
at org.grails.web.servlet.view.AbstractGrailsView.renderWithinGrailsWebRequest(AbstractGrailsView.java:71)
at org.grails.web.servlet.view.AbstractGrailsView.renderMergedOutputModel(AbstractGrailsView.java:55)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:304)
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1286)
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1041)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:984)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:54)
at org.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:77)
at org.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:67)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Someone know how I can get the values from lazy child?
Ah, almost forget,
I'm using grails in the version 3.3.11 and GORM in 6.1.12