JDBCMetadataStore vs transaction manager - spring-data-jpa

As per documentation, JDBCMetadataStore requires an instance of DataSourceTransactionManager and this makes sense. What if I'm using JPA as primary transaction manager in the application? How can I tell to JDBCMetadataStore which transaction manager it should make use when calling the #Transactional methods - assuming I have to have 2 flavours of transaction manager beans in the application. Suggestions are welcome!

I suggest you to extend that JdbcMetadataStore and override all the transactional methods with delegation to super and #Transactional with the specific TX manager:
public class MyJdbcMetadataStore extends JdbcMetadataStore {
public MyJdbcMetadataStore(DataSource dataSource) {
super(dataSource);
}
#Override
#Transactional("jdbcTransactionManager")
public String putIfAbsent(String key, String value) {
return super.putIfAbsent(key, value);
}
}

Related

Hazelcast MapStore and JPA Repository

Since many days, I try to make an Hazelcast MapStore works with a JPARepository but I cannot make it working because I cannot create a transaction:
org.springframework.dao.InvalidDataAccessApiUsageException: no transaction is in progress; nested exception is javax.persistence.TransactionRequiredException: no transaction is in progress
I know that the MapStore does not participate to the Spring transaction as stated in the documentation but I would like to explicitly create another one if needed. I tried with TransactionTemplate or PlateformTransactioManager but it seems that it has no effect:
#Autowired
private UuidSpringDataJpaRepository uuidSpringDataJpaRepository;
#Autowired
private PlatformTransactionManager platformTransactionManager;
...
#Override
public void storeAll(Map<String, V> map) {
LOGGER.info("[{}, {}] storeAll: {}", tenant, cacheType, map);
ClientDatabaseContextHolder.setTenantName(tenant);
try {
TransactionTemplate txTemplate = new TransactionTemplate(platformTransactionManager);
txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
txTemplate.execute(new TransactionCallbackWithoutResult() {
#Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
for (Entry<String, V> entry : map.entrySet()) {
storeUuidEntity(entry.getKey(), entry.getValue());
}
uuidSpringDataJpaRepository.flush();
}
});
} finally {
ClientDatabaseContextHolder.removeTenantName();
}
}
I saw already some exemples like this so this might be feasible I guess ?
Thanks for your help.
#Jerome, you can actually let MapStore participate into Spring Transaction. Use #Transactional annotation on UuidSpringDataJpaRepository or another Service and/or any related method and call that method.

spring data repository Implenation

I am using Spring DATA JPA and selected #Query annotation for creating queries (instead of using NamedQueries and Queries created from MethodName)
I have a data repository as below
public interface EventRepository extends CrudRepository<Event, Long> {
#Query("select e from Event e where e.name = :eventName)
public List<Event>findEventByName(String eventName );
}
Interface looks good and its enough as per Spring reference doc.
But I need a impl class because I need many other methods in addition to above.
I am facing 2 issues when I create EventRepositoryImpl java implementing EventRepository
Its asking to implement all the methods in EventRepository, findEventByName method is self contained in interface and why I need implement it again in Impl class?
Its asking to implement all the methods in CrudRepository, I know its per OOPS design, But there many methods
So, for these issues can I define my EventRepositoryImpl as abstract,
this seems to be working fine.
But do I need to worry about anything else, when Spring uses a abstract class as a bean.
or is there an elegant way to solve this issue.
Appreciate your help.
You do not have to implement all of these methods neither create an abstract class. Take a look into official documentation.
interface UserRepositoryCustom {
public void someCustomMethod(User user);
}
class UserRepositoryImpl implements UserRepositoryCustom {
public void someCustomMethod(User user) {
// Your custom implementation
}
}
interface UserRepository extends CrudRepository<User, Long>, UserRepositoryCustom {
// Declare query methods here
}

Spring data jpa. Partial custom repository implemantation

We can write custom implementation of repository:
interface UserRepositoryCustom {
public void someCustomMethod(User user);
}
class UserRepositoryImpl implements UserRepositoryCustom {
public void someCustomMethod(User user) {
// Your custom implementation
}
}
But what if I want customize only some methods? For example:
interface UserRepositoryCustom {
public User findByFirstName(String firstName);
#Query("select u.firstName from User u where u.age > 18")
public Set<String> findAllAdultUsers();
public void someCustomMethod(User user);
}
class UserRepositoryImpl implements UserRepositoryCustom {
//I want implement only this method
public void someCustomMethod(User user) {
// Your custom implementation
}
}
If I declare a class, which implements an interface, I have to implement all methods, but I want to write custom logic for only one method.
Is it possible to do this? Maybe I can make this class abstract? Will spring data resolve this?
I think only solution is to split methods in 2 interfaces: first - for spring query method, and second - for custom implementation, as shows in doc: http://docs.spring.io/spring-data/data-jpa/docs/current/reference/html/#repositories.single-repository-behaviour.
But I think solution with abstract class would be more natural and logic: you provide only needed method implementations and spring data do the rest for you.
Let's say you have a repository with a few methods whose implementations are generated by Spring:
interface UserRepository extends CrudRepository<User,String> {
List<User> findUserByLastname(String lastName);
}
In order to add a method with a custom implementation, you need to create another interface that only contains the methods you want to customize, and make your repository extend the custom one:
interface CustomUserRepository {
User someCustomMethod();
}
interface UserRepository extends CrudRepository<User,String>, CustomUserRepository {
List<User> findUserByLastname(String lastName);
}
You can then implement the extra methods by creating an implementation class for the new interface:
class CustomUserRepositoryImpl implements CustomUserRespository {
#Override
User someCustomMethod() {
// implementation goes here.
}
}
The class name is important here: in order for Spring to find it, it should be the name of the interface that is being extended with Impl on the end.
The implementation repository is a normal Spring bean, so you can autowire a constructor to inject various dependencies.
There is a much more detailed tutorial here: https://www.baeldung.com/spring-data-composable-repositories.

Wrapping Spring Data JPA with ApsectJ

Is it possible?
Currently I am using some aspects for my MVC controllers, what works really fine. I'm wrapping their responses and I have desired effect.
I also want to do this with Spring Data JPA repositories. But since they're generated based on the interface e.g:
public interface SomeRepository<T extends Some, ID extends Serializable> extends
BaseRepository<T, ID>, JpaSpecificationExecutor<T> {
public List<T> findById(Long id)
}
It generates me controller which is ready to use:
http://localhost:8080/findById?id=1234
I also want to wrap this controller. Is it possible?
This should work:
#Component
#Aspect
public class MyAdvice {
#Before("execution(* com.company.jpa.SomeRepository+.findById(..))")
public void intercept() { ... }
}
Basically, we are telling the framework to intercept the call to the findById method on any sub-class of SomeRepository.
Here is a sample application demonstrating this in action.

How to dispose resources with dependency injection

I'm using StructureMap to resolve references to my repository class. My repository interface implements IDisposable, e.g.
public interface IMyRepository : IDisposable
{
SomeClass GetById(int id);
}
An implementation of the interface using Entity Framework:
public MyRepository : IMyRepository
{
private MyDbContext _dbContext;
public MyDbContext()
{
_dbContext = new MyDbContext();
}
public SomeClass GetById(int id)
{
var query = from x in _dbContext
where x.Id = id
select x;
return x.FirstOrDefault();
}
public void Dispose()
{
_dbContext.Dispose();
}
}
Anyway as mentioned I'm using StructureMap to resolve IMyRepository. So when, where and how should I call my dispose method?
WARNING: please note that my views have changed, and you should consider the following advise outdated. Please see this answer for an updated view: https://stackoverflow.com/a/30287923/264697
While DI frameworks can manage lifetime of objects for you and some could even dispose objects for you after you're done using with them, it makes object disposal just too implicit. The IDisposable interface is created because there was the need of deterministic clean-up of resources. Therefore, in the context of DI, I personally like to make this clean-up very explicit. When you make it explicit, you've got basically two options: 1. Configure the DI to return transient objects and dispose these objects yourself. 2. Configure a factory and instruct the factory to create new instances.
I favor the second approach over the first, because especially when doing Dependency Injection, your code isn't as clean as it could be. Look for instance at this code:
public sealed class Client : IDisposable
{
private readonly IDependency dependency;
public Client(IDependency dependency)
{
this. dependency = dependency;
}
public void Do()
{
this.dependency.DoSomething();
}
public Dispose()
{
this.dependency.Dispose();
}
}
While this code explicitly disposes the dependency, it could raise some eyebrows to readers, because resources should normally only be disposed by the owner of the resource. Apparently, the Client became the owner of the resource, when it was injected.
Because of this, I favor the use of a factory. Look for instance at this example:
public sealed class Client
{
private readonly IDependencyFactory factory;
public Client(IDependencyFactory factory)
{
this.factory = factory;
}
public void Do()
{
using (var dependency = this.factory.CreateNew())
{
dependency.DoSomething();
}
}
}
This example has the exact same behavior as the previous example, but see how the Client class doesn't have to implement IDisposable anymore, because it creates and disposes the resource within the Do method.
Injecting a factory is the most explicit way (the path of least surprise) to do this. That's why I prefer this style. Downside of this is that you often need to define more classes (for your factories), but I personally don't mind.
RPM1984 asked for a more concrete example.
I would not have the repository implement IDisposable, but have a Unit of Work that implements IDisposable, controls/contains repositories and have a factory that knows how to create new unit of works. With that in mind, the above code would look like this:
public sealed class Client
{
private readonly INorthwindUnitOfWorkFactory factory;
public Client(INorthwindUnitOfWorkFactory factory)
{
this.factory = factory;
}
public void Do()
{
using (NorthwindUnitOfWork db =
this.factory.CreateNew())
{
// 'Customers' is a repository.
var customer = db.Customers.GetById(1);
customer.Name = ".NET Junkie";
db.SubmitChanges();
}
}
}
In the design I use, and have described here, I use a concrete NorthwindUnitOfWork class that wraps an IDataMapper that is the gateway to the underlying LINQ provider (such as LINQ to SQL or Entity Framework). In sumary, the design is as follows:
An INorthwindUnitOfWorkFactory is injected in a client.
The particular implementation of that factory creates a concrete NorthwindUnitOfWork class and injects a O/RM specific IDataMapper class into it.
The NorthwindUnitOfWork is in fact a type-safe wrapper around the IDataMapper and the NorthwindUnitOfWork requests the IDataMapper for repositories and forwards requests to submit changes and dispose to the mapper.
The IDataMapper returns Repository<T> classes and a repository implements IQueryable<T> to allow the client to use LINQ over the repository.
The specific implementation of the IDataMapper holds a reference to the O/RM specific unit of work (for instance EF's ObjectContext). For that reason the IDataMapper must implement IDisposable.
This results in the following design:
public interface INorthwindUnitOfWorkFactory
{
NorthwindUnitOfWork CreateNew();
}
public interface IDataMapper : IDisposable
{
Repository<T> GetRepository<T>() where T : class;
void Save();
}
public abstract class Repository<T> : IQueryable<T>
where T : class
{
private readonly IQueryable<T> query;
protected Repository(IQueryable<T> query)
{
this.query = query;
}
public abstract void InsertOnSubmit(T entity);
public abstract void DeleteOnSubmit(T entity);
// IQueryable<T> members omitted.
}
The NorthwindUnitOfWork is a concrete class that contains properties to specific repositories, such as Customers, Orders, etc:
public sealed class NorthwindUnitOfWork : IDisposable
{
private readonly IDataMapper mapper;
public NorthwindUnitOfWork(IDataMapper mapper)
{
this.mapper = mapper;
}
// Repository properties here:
public Repository<Customer> Customers
{
get { return this.mapper.GetRepository<Customer>(); }
}
public void Dispose()
{
this.mapper.Dispose();
}
}
What's left is an concrete implementation of the INorthwindUnitOfWorkFactory and a concrete implementation of the IDataMapper. Here's one for Entity Framework:
public class EntityFrameworkNorthwindUnitOfWorkFactory
: INorthwindUnitOfWorkFactory
{
public NorthwindUnitOfWork CreateNew()
{
var db = new ObjectContext("name=NorthwindEntities");
db.DefaultContainerName = "NorthwindEntities";
var mapper = new EntityFrameworkDataMapper(db);
return new NorthwindUnitOfWork(mapper);
}
}
And the EntityFrameworkDataMapper:
public sealed class EntityFrameworkDataMapper : IDataMapper
{
private readonly ObjectContext context;
public EntityFrameworkDataMapper(ObjectContext context)
{
this.context = context;
}
public void Save()
{
this.context.SaveChanges();
}
public void Dispose()
{
this.context.Dispose();
}
public Repository<T> GetRepository<T>() where T : class
{
string setName = this.GetEntitySetName<T>();
var query = this.context.CreateQuery<T>(setName);
return new EntityRepository<T>(query, setName);
}
private string GetEntitySetName<T>()
{
EntityContainer container =
this.context.MetadataWorkspace.GetEntityContainer(
this.context.DefaultContainerName, DataSpace.CSpace);
return (
from item in container.BaseEntitySets
where item.ElementType.Name == typeof(T).Name
select item.Name).First();
}
private sealed class EntityRepository<T>
: Repository<T> where T : class
{
private readonly ObjectQuery<T> query;
private readonly string entitySetName;
public EntityRepository(ObjectQuery<T> query,
string entitySetName) : base(query)
{
this.query = query;
this.entitySetName = entitySetName;
}
public override void InsertOnSubmit(T entity)
{
this.query.Context.AddObject(entitySetName, entity);
}
public override void DeleteOnSubmit(T entity)
{
this.query.Context.DeleteObject(entity);
}
}
}
You can find more information about this model here.
UPDATE December 2012
This an an update written two years after my original answer. The last two years much has changed in the way I try to design the systems I'm working on. Although it has suited me in the past, I don't like to use the factory approach anymore when dealing with the Unit of Work pattern. Instead I simply inject a Unit of Work instance into consumers directly. Whether this design is feasibly for you however, depends a lot on the way your system is designed. If you want to read more about this, please take a look at this newer Stackoverflow answer of mine: One DbContext per web request…why?
If you want to get it right, i'd advise on a couple of changes:
1 - Don't have private instances of the data context in the repository. If your working with multiple repositories then you'll end up with multiple contexts.
2 - To solve the above - wrap the context in a Unit of Work. Pass the unit of work to the Repositories via the ctor: public MyRepository(IUnitOfWork uow)
3 - Make the Unit of Work implement IDisposable. The Unit of Work should be "newed up" when a request begins, and therefore should be disposed when the request finishes. The Repository should not implement IDisposable, as it is not directly working with resources - it is simply mitigating them. The DataContext / Unit of Work should implement IDispoable.
4 - Assuming you are using a web application, you do not need to explicitly call dispose - i repeat, you do not need to explicitly call your dispose method. StructureMap has a method called HttpContextBuildPolicy.DisposeAndClearAll();. What this does is invoke the "Dispose" method on any HTTP-scoped objects that implement IDisposable. Stick this call in Application_EndRequest (Global.asax). Also - i believe there is an updated method, called ReleaseAllHttpScopedObjects or something - can't remember the name.
Instead of adding Dispose to IMyRepository, you could declare IMyRepository like this:
public interface IMyRepository: IDisposable
{
SomeClass GetById(int id);
}
This way, you ensure all repository will call Dispose sometimes, and you can use the C# "using" pattern on a Repository object:
using (IMyRepository rep = GetMyRepository(...))
{
... do some work with rep
}