EnityManager does not generate delete query - sql

I'm trying to delete an entity but the delete query is not generated and there's no error shown in the console :
#Override
#Transactional
public void removeClassObject(MyClassObject classObject) {
MyClassObject ip = entityManager.find(MyClassObject.class, classObject.getId());
entityManager.remove(ip);
}
Take notice : #Transactional is from springFramework package
EDIT :
All my configuration are ok, because I already have the merge and persist functions doing there job without any problem it's just the remove method which doesn't generate any sql query and does not remove the given entity.
EDIT 2 :
This is how I obtain my entityManager :
#PersistenceContext(type = PersistenceContextType.TRANSACTION)
protected EntityManager entityManager;

If you are using #Transactional annotation, you should consider using interface for your service, and not only implementation.
#Transactional will need a dynamic proxy to be created on your bean to apply the transactional logic, which can be created if your Service has an interface. Otherwise you would need to manage transaction on your own.
In answer I assume that you create entity manager with
#PersistanceContext annotation and your service has no interface.
For mor information : Spring transactions
EDIT:
Also make sure, that you have enabled transactions in your configuration. Look here for similar error but with wrong configuration LINK

Related

Flowable delegateExpression in service task is not working

The flowable version which I'm using is 6.4.1.
#Component
public class MyClass implements JavaDelegate {
#Autowired
private MySampleService mySampleService;
#Override
public void execute(DelegateExecution delegateExecution){
sampleService.doSomeTask();
}
}
Here, myClass bean would be created for class MyClass. Hence, in the bpmn, I can use it like flowable:delegateExpression="${myClass}".
But I'm getting error
"unknown property used in expression: ${myClass}"
And without delegateExpression, mySampleService would be null.
Any suggestions?
There are two ways to configure flowable:
Manually - When using ‘regular’ Spring, you also need to register the ProcessEngineFactoryBean. This will take the engineConfiguration and create a SpringExpressionManager (https://github.com/flowable/flowable-engine/blob/master/modules/flowable-spring/src/main/java/org/flowable/spring/SpringExpressionManager.java) that has access to the expression manager.
SpringBoot, provides out of the box configuration. One only need to provide the needed beans, like DataSource, AsyncExecutor, etc. (based on you the scenario) and spring boot will take care of the rest.

Save or Merge Patch Entity

I want following functionality in spring data rest.
If I post to a collection resource end point, server should check if the object exists. if it exists already it should perform the same functionality as it does with merge-patch on item resource. If object does not exist already it should create it.
Is this achievable in spring data rest. If so then how?
If it is possible in your use case, you might want to use PUT instead of POST, as PUT should work as you expected.
Solution with POST
You can achieve the desired behavior with Spring Data REST Event handlers.
Just create a Handler method which accepts your entity and annotate it with #HandleBeforeCreate. In this method, you can implement your behavior, i.e. check if the object exists and update it manually or just do nothing and let the Spring Data REST handle the entity creation.
#RepositoryEventHandler
public class EntityEventHandler {
#Autowired
private EntityService entityService;
#HandleBeforeCreate
public void handleEntityCreate(Entity e) {
if (entityService.exists(e)) {
entityService.update(e);
}
}
}
EDIT:
I just realized that you would also need to stop the create event after your update. You might try throwing a custom Exception and Handling it to return 200 and the updated entity.

Apache Shiro EhCache initialization exception: Another unnamed CacheManager already exists in the same VM

I am trying to get EhCache configured to handle authorization caching in my Apache Shiro enabled web service. Currently I am getting the following exception:
org.apache.shiro.cache.CacheException: net.sf.ehcache.CacheException: Another unnamed CacheManager already exists in the same VM. Please provide unique names for each CacheManager in the config or do one of following:
Use one of the CacheManager.create() static factory methods to reuse same CacheManager with same name or create one if necessary
Shutdown the earlier cacheManager before creating new one with same name.
My shiro.ini looks like:
[main]
...
cacheManager = org.apache.shiro.cache.ehcache.EhCacheManager
cacheManager.cacheManagerConfigFile = classpath:ehcache.xml
securityManager.cacheManager = $cacheManager
From this StackOverflow post it looks like people using Spring have gotten around this issue by forcing the CacheManager to be a singleton: Another unnamed CacheManager already exists in the same VM (ehCache 2.5).
Is anybody aware of work-arounds not using Spring initialization (I'm working within the dropwizard framework and have no need to pull in Spring)? Is there some manner of enforcing singleton configuration from the shiro.ini?
Thank you in advance!
Create a custom class that extends EhCacheManager and set your cacheManager in the constructor. This (net.sf.ehcache.CacheManager.create()) allows you to reuse an already existing cachemanager.
package lekkie.omotayo
public class MyShiroCacheManager extends EhCacheManager
{
public CacheManager()
{
setCacheManager(net.sf.ehcache.CacheManager.create());
}
}
Then you can do this:
cacheManager = lekkie.omotayo.MyShiroCacheManager
cacheManager.cacheManagerConfigFile = classpath:ehcache.xml
securityManager.cacheManager = $cacheManager

Log specific NHibernate SQL queries

I know how to configure NHibernate and log4net to log the resulting SQL of my queries. Is it possible, however, to log only specific queries (for example activating the logging activity before a LINQ query and deactivating it right after the query)?
You can programmatically add and remove appenders to an instance of log4net. So what you could do is when you hit a query that you want to log, programmatically add a new appender, run the query, and then programmatically remove the appender. I have not tested this but I think this should be possible.
Here is a reference for how to programmatically add appenders.
You may log the SQL by yourself with an interceptor, which you would enable when needed.
public class SqlLogInterceptor : EmptyInterceptor
{
private static readonly ILog _log =
LogManager.GetLogger(typeof(SqlLogInterceptor ));
public bool Enabled { get; set; }
public override SqlString OnPrepareStatement(SqlString sql)
{
// Adjust your log level as you see fit.
if (Enabled)
_log.Info(sql);
return sql;
}
}
When opening the session, provide an instance of the interceptor to OpenSession and keep a reference on it.
Set its Enabled property when you need your logging. Provided you have used the interceptor instance with only one session, it will then log only that session SQL.
Parameter values will not be logged with this solution.

SessionFactory - one factory for multiple databases

We have a situation where we have multiple databases with identical schema, but different data in each. We're creating a single session factory to handle this.
The problem is that we don't know which database we'll connect to until runtime, when we can provide that. But on startup to get the factory build, we need to connect to a database with that schema. We currently do this by creating the schema in an known location and using that, but we'd like to remove that requirement.
I haven't been able to find a way to create the session factory without specifying a connection. We don't expect to be able to use the OpenSession method with no parameters, and that's ok.
Any ideas?
Thanks
Andy
Either implement your own IConnectionProvider or pass your own connection to ISessionFactory.OpenSession(IDbConnection) (but read the method's comments about connection tracking)
The solution we came up with was to create a class which manages this for us. The class can use some information in the method call to do some routing logic to figure out where the database is, and then call OpenSession passing the connection string.
You could also use the great NuGet package from brady gaster for this. I made my own implementation from his NHQS package and it works very well.
You can find it here:
http://www.bradygaster.com/Tags/nhqs
good luck!
Came across this and thought Id add my solution for future readers which is basically what Mauricio Scheffer has suggested which encapsulates the 'switching' of CS and provides single point of management (I like this better than having to pass into each session call, less to 'miss' and go wrong).
I obtain the connecitonstring during authentication of the client and set on the context then, using the following IConnectinProvider implementation, set that value for the CS whenever a session is opened:
/// <summary>
/// Provides ability to switch connection strings of an NHibernate Session Factory (use same factory for multiple, dynamically specified, database connections)
/// </summary>
public class DynamicDriverConnectionProvider : DriverConnectionProvider, IConnectionProvider
{
protected override string ConnectionString
{
get
{
var cxnObj = IsWebContext ?
HttpContext.Current.Items["RequestConnectionString"]:
System.Runtime.Remoting.Messaging.CallContext.GetData("RequestConnectionString");
if (cxnObj != null)
return cxnObj.ToString();
//catch on app startup when there is not request connection string yet set
return base.ConnectionString;
}
}
private static bool IsWebContext
{
get { return (HttpContext.Current != null); }
}
}
Then wire it in during NHConfig:
var configuration = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2005
.Provider<DynamicDriverConnectionProvider>() //Like so