So, is it not recommended using an inheritance-approach when implementing Grails services? I went through a simple service specialization pattern understanding that all would work in a transparent way, but I started to go into trouble regarding transaction management under the spring/grails hood. Issues happen when a method from the specialized class calls a method from the inherited class (both concrete services themselves):
#Transactional
public class MammalService {
public mammalMethod() {
}
}
#Transactional
public class DogService extends MammalService {
public dogMethod() {
mammmalMethod()
}
}
It comes that when the inherited method is called from the specialized one, org.springframework.transaction.support.GrailsTransactionTemplate() constructor is fired (by the spring/grails transaction AOP) with a null transactionManager argument, which causes some NullPointerException moreover.
Has anyone used such approach with services? Am I missing something?
PS: Curiously, I tried changing the #grails.transaction.Transactional annotation by the #org.springframework.transaction.annotation.Transactional and the NullPointerException ceased from happening. (Nevertheless, it didn't point to a nice solution, since other side effects started to happen with my pool management).
UPDATE1: While debugging, I can see TWO variables with the same name transactionManager inside my specialized service (something that doesn't happen when inspecting the concrete superclass).
I'm opening a more specific issue at Duplicated transactionManager property in Grails service
Solved by removing #Transaction from specialized service classes and
methods, keeping them only on the inherited service class and its methods.
#Transactional
public class MammalService {
#Transactional(readonly=true)
public mammalMethod() {
}
}
//Don't annotate with #Transactional - rely on the super class declaration
public class DogService extends MammalService {
//Don't annotate with #Transactional - rely on the super class transactional declaration
public dogMethod() {
mammmalMethod()
}
}
It seems that, for specialized service classes, the transaction routines try to re-inject the transactionManager attribute, resulting in two attributes with the same name and one of them null. Also, annotating overrided methods raises an StackOverflowException.
Related
If I annotate a class with #Transactional like so:
#Transactional
class MyService { ... }
Is that the same as annotating all of its methods with #Transactional like so:
class MyService {
#Transactional
void myFunction() { ... }
}
There are also some other things to consider such as: how does this propagate to sub classes, inner classes, and static methods?
From the
documentation
…The result is that all methods are wrapped in a transaction and
automatic rollback occurs if a method throws an exception (both Checked
or Runtime exceptions) or an Error…
So yes it is the same.
how does this propagate to sub classes
It is inherited - but it is recommended to annotate only concrete classes
inner classes
AFAIK not.
If any I would only define POJOs as an inner class - business logic
always goes into services
static methods
AFAIK not
I have the following super class grails service:
abstract class SuperClassService {
public def execute(def payload) {
def tracker = new TrackerDomain().save()
doWork()
tracker.status = 'done'
tracker.save()
}
protected abstract doWork(def payload);
}
and seveeral child class grails services that follow this pattern:
class SubClassService extends SuperClassService {
protected doWork(def payload){
new SomeDomain().save()
}
}
In my controllers I kick off a call to the 'execute' method of the various child classes.
What I want is for the SubClass services to follow the traditional Service pattern where any problems get rolled back, but I want the domains created int he parent class code to both NOT be rolled back and be committed immediately (so that they can be viewed on a tracking page while the subclass service code is still executing. I would PREFER not to set everything as non-transactional and only set the functions in the subclass as transactional but if that's the only option here I would like to know that too.
Have you tried annotating your subclasses service method with a #Transactional(propagation = Propagation.REQUIRES_NEW)? I think that it should do the trick, regardless of whether the outside service code is transactional or not.
My rich domain model has some circular reference, and this is intentional.
I am also writing my own ORM for more control, and to detect changes made to properties I am using Unity to intercept any call to setters and trigger the property change notification (similar with how EF works).
The problem is that I'm getting Stack Overflow, because the policy interception is going over the same object, over and over again. Is there a way to make it do reference counting?
I have already made sure that the constructor aren't circularly dependent, but I still need Policy Injection to stop recursing over the same objects repeatedly.
Instead of injecting the objects, you can inject the functions to built them, when you have a circular reference:
Container.RegisterType<IMyService, ImplService>(... );
public class MyClass {
private Func<IMyService> _serviceProvider;
public MyClass(Func<IMyService> serviceProvider) { _serviceProvider = serviceProvider }
public void DoStuff() {
_serviceProvider().DoSomething();
}
}
Unity will inject a function that returns IMyService
I have an interface
public interface ILoggerService
{
void Info(string message);
void Warn(string message);
}
Then, i have a class which implements this interface and logs using Log4Net
public class Log4NetLoggerService : ILoggerService
{
private readonly ILog _logger;
public Log4NetLoggerService()
{
// this always returns Log4NetLoggerService class type
_logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
}
public void Info(string message)
{
_logger.Info(message);
}
}
This works fine, but the problem is that if i want to log the current class and method name, (using %class - %M), this always returns Log4NetLoggerService as the class, and as the method it returns Info as the method.
I need to get the "parent" class type, which called the logging method.
Can i inject somehow the type of the class which calls the log methods when i create the ILoggerService instance?
Have a look at the log4net source code; specifically how they implemented the ILog interface. You basically cannot use the ILog interface in your wrapper, instead you use the internal logger which accepts a parameter that instructs log4net where to look for the correct class / method in the call stack. See also this answer.
In my experience, if you need the name of the class you're logging in, you're probably logging too much and from too many places in your application. This can lead to maintenance problems. Take a look at this Stackoverflow answer to verify if you're not logging too much and if you're not violating the SOLID principles.
I frequently use AutoMapper to map Model (Domain) objects to ViewModel objects, which are then consumed by my Views, in a Model/View/View-Model pattern.
This involves many 'Mapper.CreateMap' statements, which all must be executed, but must only be executed once in the lifecycle of the application.
Technically, then, I should keep them all in a static method somewhere, which gets called from my Application_Start() method (this is an ASP.NET MVC application).
However, it seems wrong to group a lot of different mapping concerns together in one central location.
Especially when mapping code gets complex and involves formatting and other logic.
Is there a better way to organize the mapping code so that it's kept close to the ViewModel that it concerns?
(I came up with one idea - having a 'CreateMappings' method on each ViewModel, and in the BaseViewModel, calling this method on instantiation. However, since the method should only be called once in the application lifecycle, it needs some additional logic to cache a list of ViewModel types for which the CreateMappings method has been called, and then only call it when necessary, for ViewModels that aren't in that list.)
If you really don't want to use a bootstrapper, then at least a static constructor is an easy way of ensuring your CreateMap is called at most once. (With less messing around and more thread proof than Jonathon's answer.)
public class AccountController : Controller
{
static AccountController()
{
Mapper.CreateMap<Models.User, ViewModels.UserProfile>();
Mapper.CreateMap<Models.User, ViewModels.ChangePassword>();
}
}
If you use profiles, you can place all of your "CreateMap" calls there. Additionally, you can create a static bootstrapper class that contains your configuration, and have the startup piece just call the bootstrapper.
OK, the way I'm currently doing it is this:
I add some logic to the constructor of my BaseController, which runs the 'CreateMappings' method, but only once per Controller Type:
public abstract class BaseController : Controller
{
public BaseController()
{
if (!controllersWithMappingsCreated.Contains(GetType()))
{
CreateMappings();
controllersWithMappingsCreated.Enqueue(GetType());
}
}
protected virtual void CreateMappings() { }
}
In each concrete controller, I use CreateMappings to declare the mappings for all the Models/ViewModels relevant to that controller.
public class AccountController : BaseController
{
public AccountController() : base() { }
protected override void CreateMappings()
{
Mapper.CreateMap<Models.User, ViewModels.UserProfile>();
Mapper.CreateMap<Models.User, ViewModels.ChangePassword>();
}
}
I also found some interesting alternatives involving Attributes here and here, however they strike me as a bit overcomplicated.