Serviço em Dominio
12/09/2012 17:39
0
Pessoal,

alguem poderia me dizer como faço para usar uma função de serviço diretamente em um dominio?

Criei o serviço e o declarei no dominio como:

transient ServicoService


também testei como:
def ServicoService
e não funcionou.

Minha função, dentro do dominio fica assim:

def beforeInsert(){
protocolo = ServicoService.inserirProtocolo


Aparece sempre a mesma mensagem:

ERROR context.GrailsContextLoader - Error executing bootstraps: No such property: inserirProtocolo for class: com.aplicacao.ServicoService
Message: No such property: inserirProtocolo for class: com.aplicacao.ServicoService
Line | Method
->> 108 | inserirProtocolo in com.aplicacao.Servico
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 94 | beforeInsert in ''
| 46 | onApplicationEvent in org.grails.datastore.mapping.engine.event.AbstractPersistenceEventListener
| 334 | innerRun in java.util.concurrent.FutureTask$Sync
| 166 | run . . . . . . . in java.util.concurrent.FutureTask
| 1110 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 603 | run . . . . . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run in java.lang.Thread


Alguem sabe como fazer com que a função seja executada em meu dominio. Ela retorna uma String com o protocolo do serviço.
Tags: serviço, service


0
Brother no caso não seria

def servicoService


Ao invés de

def ServicoService




0
Isso aí Garbiel ;-)
12/09/2012 18:21


0
Desculpe eu que digitei errado aqui... mas esta
def servicoService
12/09/2012 18:31


0
Ilmon, segundo a mensagem

Message: No such property: inserirProtocolo for class: com.aplicacao.ServicoService

O erro não seria porque você está invocando 'inserirProtocolo' sem os parenteses ?
12/09/2012 18:36


0
Eu pensei que fosse isso porém não é... coloquei os parentes e não compilou deu erro estranho (is applicable for argument types: () values: []), retirei e consegui compilar. O Argumento a ser passado pela função é facultativo, porém não chega nem a executar a função.

12/09/2012 20:06


0
Verifique se o seu método inserirProtocolo na classe com.aplicacao.ServicoService está definido como public.

12/09/2012 20:36


0
Me refiro ao modificador de acesso do get e set.
12/09/2012 20:47


0
Como assim Nathan.... me dê um exemplo....

Minha função está definida no Service como


String inserir Protocolo(){
...
}
12/09/2012 21:09


0
tentei
public String inserirProtocolo(){
...
}


mas também nao funcionou
12/09/2012 21:57


0
Pergunta sobre grails relacionada a questão reportada:

Ao declarar no seu domain um atributo transient ServicoService, vc nao esta apenas criando uma referencia a classe de servico? A classe de servico funciona como uma classe abstrata e permite executar um metodo sem haver uma instancia?

Não deveria ser algo do tipo:

transient ServicoService ss = new ServicoService()

def BeforeInsert{
Protocolo = ss.inserirProtocolo
}

...Para poder haver na referencia ss criada uma instancia da classe?

P.S.: Sou mt novo em prog Java principalmente Grails/Groovy...ignorem se eu estiver falando #$%¨@#$.
13/09/2012 00:31


0
Tente assim no service


def inserirProtocolo(){
...
}


e na hora de invocar coloque

def beforeInsert(){
protocolo = ServicoService.inserirProtocolo
}
13/09/2012 10:57


0
Perdão (é que eu copiei o seu código pra aproveitar rs)

A declaração é :


def inserirProtocolo(){
...
}


e assim a invocação

def beforeInsert(){
def servicoService
protocolo = servicoService.inserirProtocolo
}
13/09/2012 10:59


0
Eita, faltaram os parenteses

def beforeInsert(){
def servicoService
protocolo = servicoService.inserirProtocolo()
}
13/09/2012 11:01


0
E aí Ilmon, funcionou ??? :)
13/09/2012 13:15


0
Opa! Tomara q funcione a solução q o Pedro deu, pq aí eu tava certo: A classe de serviço não é abstrata por padrão e precisa de uma instância "...def servicoService..." gera a instância.

Obrigado também pelo apoio Pedro, mesmo eu estando "pongando" pra aprender com a duvida de outros.
13/09/2012 13:36


0
Opa...não teria q ter um construtor?

Se eu não atribuí nada à def servicoService, como ele sabe q se trata da classe ServicoService?

Se eu tivesse jogado uma instancia dentro dela eu até entendo que dinamicamente ele assuma o tipo da instância, mas sem atribuir nada, como ele faz isso?

def beforeInsert(){
def servicoService = new ServicoService()
protocolo = servicoService.inserirProtocolo
}
13/09/2012 13:42


0
Pessoal,

ainda não funcionou... continua dando a mesma mensagem de compilação:

| Error 2012-09-13 11:00:55,627 [pool-5-thread-1] ERROR context.GrailsContextLoader - Error executing bootstraps: No signature of method: static com.aplicacao.ServicoService.InserirProtocolo() is applicable for argument types: () values: []


Possible solutions: InserirProtocolo()
Message: No signature of method: static com.aplicacao.ServicoService.InserirProtocolo() is applicable for argument types: () values: []
Possible solutions: InserirProtocolo()

O problema continua ocorrendo. Eu mando criar uma instancia do objeto no bootstrap e esta instancia usa este serviço.



Mauricio,

com serviços não precisa de instanciá-los com o metodo 'new' apendas declará-lo como 'def' o mesmo já é encontrado. 'New' é pra quando vc deseja criar um objeto.
13/09/2012 14:57


0
Ilmon o que pode estar acontecendo é que não está injetando o service no Domain, faça um teste pra ver se funciona, coloque estes comandos de pegar o protocolo de beforeInsert no método do controller para ver se neste contexto o serviço é injetado.

Mauricio na verdade não precisa pois o Spring deveria injetar pra nós uma instância daquele Servico, por convenção.

"A key aspect of Grails services is the ability to use Spring Framework's dependency injection features. Grails supports "dependency injection by convention". In other words, you can use the property name representation of the class name of a service to automatically inject them into controllers, tag libraries, and so on.

As an example, given a service called BookService, if you define a property called bookService..."

Texto estraído da documentação do grails.
13/09/2012 18:48


0
Pedro,

se eu fizer uso do Service no Controller funciona normalmente, porém eu estruturei o programa para fazer uso pelo Dominio. Daí quando utilizo o mesmo no dominio ocorre esses erros. Eu poderia alterar o Service para fazer uso dele somente no Controller, mas quero saber o porque dessa incompatibildiade.

O estranho é que se vc observar no plugin 'Spring Security Core', o mesmo invoca metodos do Service deiretamente no dominio. Se neste plugin eles fazem uso porque esse erro ocorre quando eu tento usar um Service em meu dominio. Tem alguma explicação entende? Acho que é isso que todo mundo esta interessado, em saber o porque que o Service não funciona do Dominio, mesmo sendo possível funcionar como é o caso do plugin.
13/09/2012 19:46


1
É muito estranho porque na documentação fala que pode injetar no domain e tal, e é como você está fazendo, a única diferença é que o def servico está na área das variáveis de instância, assim :


class Book {

def bookService
def buyBook() {
bookService.buyBook(this)
}
}


Outra possível solução é tentar pegar o Bean do service direto do contexto da aplicação. Este link tem uma explicação de como fazer isso.

Depois poste aí qual das duas deu certo ;-) (Olha a confiança rs)
13/09/2012 20:27


0
Ilmon e Pedro...obrigado pelas infs!
13/09/2012 21:55


0
Disponha Maurício :-)
13/09/2012 23:14


0
Pessoal,

ainda não funcionou! Pedro, acho estranho que o erro cotinua o mesmo. A documentação realmente diz isso. Fiz tudo conforme a documentação e não descobri o porque desse problema.

Não sei se eu estou errando ou se é algu bug do Grails. Mas estou curioso para saber como fazer isso funcionar conforme a documentação.
14/09/2012 13:04


0
Ilmon,

você ja tentou fazer algum teste criando uma aplicação do zero e um serviço que altera o status de um atributo?

Eu ja tentei usar o Service fora do controler e tive problemas semelhantes, mas realmente na documentação diz que isso é possível.

14/09/2012 15:27


1
O grails deve permitir isso ate mesmo porque toda lógica de negocio é recomendável ficar nos Services. Se vc realmente começar a usar tais regras no Dominio ao invés do Service vai complicar seu código.

14/09/2012 15:29


0
Talvez seja mesmo um Bug no próprio Grails.
14/09/2012 15:30


0
Ilmon, não funcionou nem tentando conseguir o Service direto do contexto de aplicação conforme o link que eu te passei ?
14/09/2012 16:58


0
Pedro,

eu não tentei pelo seu tutorial, apenas pela documentação do Grails que vc referenciou.

Sou leigo me dá uma força aqui... em seu tutorial Onde eu insiro este primeiro codigo:

def service = ApplicationHolder.application.getMainContext.getBean("${property}Service")


Tenho que alterar alguma coisa?

a sequencia:


import grails.util.GrailsNameUtils

String beanName = GrailsNameUtils.getPropertyName(property) + 'Service'
def service = ApplicationHolder.application.getMainContext.getBean(beanName)


Meu Código esta no padrao da documentação do Grails:

Class Servico{
def ServicoService

def beforeInsert(){
protocolo = servicoService.inserirProtocolo()
}
}


No meu ServicoService esta:


String inserirProtocolo(){
...
}


Por favor me ensine como posso usar essa injeção de dependencia. Obrigado pela ajuda.


14/09/2012 17:23


0
Estou vendo o seu código no seu domain o servico está com a primeira maiúscula assim ? :


class Servico {
// Errado
def ServicoService

// Correto
def servicoService

def beforeInsert(){
protocolo = servicoService.inserirProtocolo()
}
}


outro detalhe é que o seu método
String inserirProtocolo(){}
pode ficar apenas assim
def inserirProtocolo(){}


Continuando para pegar pelo contexto de aplicação o seu seu Domain fica assim :


Class Servico{
// Lembre sempre que a propriedade é com a primeira minúscula, se ficar maiúscula dá não injeta.
def sevicoService = ApplicationHolder.application.getMainContext.getBean('servicoService')

def beforeInsert(){
protocolo = servicoService.inserirProtocolo()
}
}
14/09/2012 17:49


0
Pedro,

Eu digitei aqui errado, mas no codigo estava certo. Ainda não funcionou. Deu o seguinte erro:

| Error 2012-09-14 15:08:57,214 [pool-5-thread-1] ERROR context.GrailsContextLoader - Error executing bootstraps: Error creating bean with name 'transactionManagerPostProcessor': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager': Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': Invocation of init method failed; nested exception is org.hibernate.InstantiationException: could not instantiate test objectcom.aplicacao.registros.Servico
Message: Error creating bean with name 'transactionManagerPostProcessor': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager': Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': Invocation of init method failed; nested exception is org.hibernate.InstantiationException: could not instantiate test objectcom.aplicacao.registros.Servico
Line | Method
->> 334 | innerRun in java.util.concurrent.FutureTask$Sync
14/09/2012 18:25



Ainda não faz parte da comunidade???

Para se registrar, clique aqui.


Aprenda Groovy e Grails com a Formação itexto!

Newsletter Semana Groovy

Assinar

Envie seu link!


Livro de Grails


/dev/All

Os melhores blogs de TI (e em português) em um único lugar!

 
Creative Commons
RSS Grails Brasil é mantido por itexto Consultoria.
Em caso de problemas contacte Henrique Lobo Weissmann (Kico) por e-mail: kico@itexto.com.br
Todo o conteúdo presente neste site adota o Creative Commons como licença padrão.
Ver: 4.14.0
itexto