grails: maintain transactional context from Service to Controller - grails

Have a transaction in a grails Service class on which a rollback flag is set:
TransactionAspectSupport
.currentTransactionInfo()
.transactionStatus
.setRollbackOnly()
what happens is that when we return to the Controller an exception:
org.springframework.transaction.UnexpectedRollbackException
which we have to catch in the Controller (but not in any of the Service classes). This code is being refactored from the previous solution where all the logic happened direct in the Controller. Any advise on what happens that trips this exception to be thrown when the method returns, given that:
static transactional = true
has been set on all the classes. Guessing theres some subtle Controller verses Service magic happening - does anyone know about this? For now just catching the exception as a workaround, but this loses the TransactionStatus object that otherwise would have been returned.
Any thoughts much appreciated

Transaction management in Grails is pretty ugly (for me).
So i'm proffering Spring declarative transactions:
Chapter 9. Transaction management
They works perfectly in grails services.
Returning back to setRollbackOnly(). This method is not simple... While you have set RollBack=true in your inner transaction you have triggered to rollback your outer transaction to sou you are getting exception.
I've similar problem some time ago - here is useful info to find best solution suiting for you:
AbstractPlatformTransactionManager.setGlobalRollbackOnParticipationFailure(false)
Grails - Declarative Transactions
Declarative transactions don't works in 1.3.x ?

Related

What's the best way to ensure an instance of a domain class is not changed or modified

When I retrieve a domain instance via GORM, there is the possible danger of code modifying that instance/row. Especially because Grails automatically saves it even without calling .save() on the instance.
The only way I've ensured this before is making sure I call discard() on the instance in the past. Is there a better way?
This is for Grails 2.2.5
What version of Grails/GORM?
An option would be do this work in a #ReadOnly (or #Transactional(readOnly = true)) Transaction - an exception will be thrown if an write operation is attempted.
If you want to always require manual .save() calls, that's possible by changing the hibernate.flush.mode though even that has its risks. Using .discard() is your best bet in most cases. As Anton points out, you can use .isDirty() to find out if anything has changed, but that will not prevent the save from occurring.

Grails 2 app ported to Grails 3 - PooledConnection has already been closed, solved but not sure why

I was getting a "PooledConnection has already been closed" error when executing a controller with a method that performs a groovy sql query against the dataSource like this
class MyController {
def sessionFactory
def viewWeek (ThingCommand cmd) {
def summary = summaryService()
def db = new Sql(sessionFactory.currentSession.connection())
def sqlStrFind = "SELECT * FROM mytable"
def weekList = db.rows(sqlStrFind)
}
}
In Grails 2 I had seen runtime issues when ordering a Service.method call after inline use of a sessionFactory connection, but not the order above.
This led me to try refactoring the inline code into a new Service. This made the code work, but I noticed that #Transactional was annotating the new Service class, so I guessed that annotating class MyController with #Transactional might do the same for the Controller - and I was correct.
What I don't understand is why #Transactional makes a difference when I thought that Controllers and Services were transactional by default - or did something change in Grails 3?
BTW Burt Beckwith promoted the use of sessionFactory connection as this gave you a pooled connection
#virtualdogbert on slack grails-community provided this answer, which answers my question:
Some where in the Grails 3 line they removed the automatic transaction proxies by default, but you could bring them back with a config change
[see application.yml - grails: spring: transactioManagement: proxies: false ]
The #Transaction(Grails version) was added because it used an AST transform rather than a spring proxy, which in my mind makes it more reliable. Using the AST transform, was promoted over using the proxies for this reason.
The #Transactional AST transform also gives you greater control over how your transactions work.
Even though it's shown in examples I wouldn't use #Transactional in controllers, because it's considered bad practice.
Your​ business logic should be in services - controllers should just be use for routing, and rendering.

In StructureMap 4, why might using a lambda-created default instance result in a NotSupportedException?

I'm in the process of migrating to StructureMap 4 (specifically version 4.0.1.318).
I have what looks to me like appropriate object registration:
For<ISomeInterface>().Use(() => GetConcreteInstance());
For<ISomeInterface>().MissingNamedInstanceIs.TheDefault();
For<ISomeOtherThing>().Add<OtherConcreteClass>()
.Ctor<ISomeInterface>().IsNamedInstance("Special");
However, if no "Special" instance of ISomeInterface is configured (which would typically occur in another Registry, if it needs to happen), then rather than falling back to the default instance (which is what I would expect) a call like this
[Container].GetAllInstances<ISomeOtherThing>();
results in the following: System.NotSupportedException: Instance's of type 'StructureMap.Pipeline.DefaultInstance' does not support ToNamedClose() and cannot be used as a MissingInstance
I'm guessing something is wrong in my registration... but what?
Based on a conversation with Jeremy Miller in StructureMap's Gitter IM channel, it seems as if this is an oversight in the current implementation, and is likely to be fixed shortly.
For anyone else needing it, the bug report can be found at https://github.com/structuremap/structuremap/issues/438

Grails Cache and EHCache Plugin caches Controller methods but not Service methods

I'm having trouble getting the Grails EHCache Plugin to cache service methods. Here is my setup:
Grails 2.4.2, JDK 1.7
BuildConfig.groovy compile ":cache-ehcache:1.0.4"
Config.groovy defines the following cache named "cache"
grails.cache.config = {
cache {
name 'cache'
timeToLiveSeconds 60
}
}
The following controller method properly caches. I have tested by setting a breakpoint in the method, and it only is hit the first time, until the cache expires.
#Cacheable('cache')
def index() {
render "index-$params.id"
}
I can check the keys in the cache with:
grailsCacheManager.getCache('cache').getNativeCache().getKeys()
and see the value:
localhost:GET:/grails-cache-test/cache/index?id=34
So far so good.
The following service method exists:
#Cacheable('cache')
public method1(id) {
"method1+$id"
}
I set a break point in here, and this method is always called, regardless of the #Cacheable annotation. I've tried setting the value and key annotation attributes manually, and no change. I test calling this method from a non-cached controller method, as well as directly from the console plugin. When I get the keys in the service method I see that there are no keys set.
I've looked through examples in the official documentation, code samples online, github, a book I have, everything looks good, so I'm not sure where the problem lies.
Any ideas on why this service method does not cache the value? Thanks!
UPDATE 1
I've been digging into the grails cache-1.1.8 plugin (as well as the associated cache-ehcache-1.0.4 plugin), and believe I've found something helpful. In PageFragmentCachingFilter.doFilter() there are calls to check the controller's annotations - but nothing to check the service. It appears that as a result, the service annotations are never honored. There is a lot of documentation that mentions service methods, so I don't know if there is something elsewhere that handles this, or if it's a less common use case compared to controller methods.
UPDATE 2
It appears that Controllers and Services are handled separately. In CacheAspectSupport.execute() there is a for() loop that will call cachePutRequest.apply(result.get());, which will actually add the entry to the cache. Unfortunately after the entry is added to the request, it is not immediately available to be retrieved. The underlying put() code is part of Spring Source, so at this point I'm not sure if it's a grails plugin issue or a Spring Source issue.
I have created a JIRA issue for this plugin GPCACHEEHCACHE-16

Exception thrown Constructor Injection - AutoFac Dependency Injection

I have an Autofac DI Container and use constructor injection to inject configuration settings into my SampleClass. The Configuration Manager class is created as a singleInstance so the same single instance is used.
public ConfigurationManager()
{
// Load the configuration settings
GetConfigurationSettings();
}
public SampleClass(IConfigurationManager configurationManager)
{
_configurationManager = configurationManager;
}
I am loading the configuration settings from a App.config file in the constructor of the configuration Manager. My problem is i am also validating the configuration settings and if they are not in the App.config file a exception is thrown, which causes the program to crash. Which means I cant handle the exception and return a response.
I am doing this the wrong way? Is there a better way to load the configuration settings Or is there a way to handle the exception being thrown.
Edit
ConfigurationManager configurationManager = new ConfigurationManager();
configurationManager.GetConfigurationSettings();
//Try catch around for the exception thrown if config settings fail
//Register the instance above with autofac
builder.Register(configurationManager()).As<IConfigurationManager>().SingleInstance();
//Old way of registering the configurationManager
builder.Register(c => new ConfigurationManager()).As<IConfigurationManager>().SingleInstance();
You are doing absolutely the right thing. Why? You are preventing the system from starting when the application isn't configured correctly. The last thing you want to happen is that the system actually starts and fails later on. Fail fast! However, make sure that this exception doesn't get lost. You could make sure the exception gets logged.
One note though. The general advice is to do as little as possible in the constructor of a type. Just store the incoming dependencies in instance variables and that's it. This way construction of a type is really fast and can never really fail. In general, building up the dependency graph should be quick and should not fail. In your case this would not really be a problem, since you want the system to fail as soon as possible (during start-up). Still, for the sake of complying to general advice, you might want to extract this validation process outside of that type. So instead of calling GetConfigurationSettings inside that constructor, call it directly from the composition root (the code where you wire up the container) and supply the valid configuration settings object to the constructor of the ConfigurationManager. This way you -not only- make the ConfigurationManager simpler, but you can let the system fail even faster.
The core issue is that you are mixing the composition and execution of your object graph by doing some execution during composition. In the DI style, constructors should be as simple as possible. When your class is asked to perform some meaningful work, such as when the GetConfigurationSettings method is called, that is your signal to begin in earnest.
The main benefit of structuring things in this way is that it makes everything more predictable. Errors during composition really are composition errors, and errors during execution really are execution errors.
The timing of work is also more predictable. I realize that application configuration doesn't really change during runtime, but let's say you had a class which reads a file. If you read it in the constructor during composition, the file's contents may change by the time you use that data during execution. However, if you read the file during execution, you are guaranteed to avoid the timing issues that inevitably arise with that form of caching.
If caching is a part of your algorithm, as I imagine it is for GetConfigurationSettings, it still makes sense to implement that as part of execution rather than composition. The cached values may not have the same lifetime as the ConfigurationManager instance. Even if they do, encoding that into the constructor leaves you only one option, where as an execution-time cache offers far more flexibility and it solves your exception ambuguity issue.
I would not call throwing exceptions at composition-time a good practice. It is so because composition might have a fairly complex and indirect execution logic making reasonable exception handling virtually impossible. I doubt you could invent anything better than awful
try
{
var someComponent = context.Resolve<SampleClass>();
}
catch
{
// Yeah, just stub all exceptions cause you have no idea of what to expect
}
I'd recommend redesigning your classes in a way that their constructors do not throw exceptions unless they do really really need to do that (e.g. if they are absolutely useless with a null-valued constructor parameter). Then you'll need some methods that initialize your app, handle errors and possibly interact with user to do that.

Resources