I have situation like this
I have controller code
#RestController
public class MyController implements SomeApi {
#Autowired
private final MyService myService ;
public ResponseEntity<AnswerObject> getSomething (RestModelObject obj) {
myService.getSomething(obj);
}
Below Service code:
#Service
public class MyServiceImpl implements MyService {
#Autowired
private final EntityRepository entityRepository;
public AnswerObject getSomething (RestModelObject obj) {
Entity entity = entityRepository.getSomething(obj);
AnswerObject answerObject = map(entity, new AnswerObject());
return answerObject;
}
}
I have here few layers as I can see - rest layer, business layer, persistence layer (let's suppose I have few data sources - DB and elastic, each have some repository bean).
As we can see Business layer (service) aware about entities, which is not really good I think.
So question is what is the best practices for this situation?
Mapping should happen on persistence layer?
Or Is it good idea to create some additional layer adapter which will be responsible for mappings between rest models to internal data models, and inject it to the service bean ?
Appreciate any good mature examples.
I think, it can be done on controller's level, like in example here. Correct me If I am wrong.
Related
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
}
I'm building a service application using Web API, .Net Core and EntityFramework Core.
For configuring options in my DbContext I'm using these lines in "ConfigureServices" method in Startup.cs
var connection = #"Server=ISSQLDEV;Database=EventManagement;Trusted_Connection=True;";
services.AddDbContext<EMContext>(options => options.UseSqlServer(connection));
I know that if I add the context as a constructor parameter in the controller .Net will inject the context in the constructor.
But this is not the behavior I want. I don't want my web api to know anything about the dbcontext. I have a DataAccess Project with a repository class that handles all CRUD operations.
This means that I just want to say Repository.AddEvent(evt) in my controller and then repository knows how to handle that.
On the other hand, repository uses a simple dependency resolver to get the right "IDataAdapter" implementation. One of those implementations is SQLDataAdapter. This is the point I need my context.
How can I pass my context all the way to this point?
You can solve this by adding your dbcontext via constructor injection to your classes from your data access layer.
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(o => o.UseSqlServer(myConnStr));
services.AddScoped<Repository>(); // 'scoped' in ASP.NET means "per HTTP request"
}
}
public class MvcController
{
private Repository repo;
public MvcController(Repository repo)
{
this.repo = repo;
}
[HttpPost]
public void SomeEndpoint()
{
this.repo.AddFoo(new Foo());
}
}
public class Repository
{
private DbContext db;
public Repository(ApplicationDbContext db)
{
this.db = db;
}
public void AddFoo(Foo obj)
{
this.db.Set<Foo>().Add(obj);
this.db.SaveChanges();
}
}
If you want to further customize how your DbContext is injected into your DI container, I suggest you look at what .AddDbContext is actually doing. See https://github.com/aspnet/EntityFramework/blob/1.0.0/src/Microsoft.EntityFrameworkCore/EntityFrameworkServiceCollectionExtensions.cs#L142-L158
I try to autowire my custom mongo repository (and it seems the constructor is executed) but still the result is null
I've looked at some similar questions
Spring Data Neo4j - #Autowired Repository == null
and
spring data mongo repository is null
but I still don't know how to solve this.
public class TestRepo {
#Autowired
PersonRepository repository;
public void find(String name)
{
System.out.println(repository.findByName(name));
}
}
config
<mongo:repositories base-package="com.yyyy.zzz" />
PersonRepository
public interface PersonRepository extends Repository<Person, BigInteger> {
#Query("{name : ?0}")
public Person findByName(String name);
}
Implementation
public class PersonRepositoryImpl implements PersonRepository{
PersonRepositoryImpl()
{
System.out.println("constructing");
}
public Person findByName(String name) {
...
}
}
if I get the repository bean directly from context it works
Your repository setup looks suspicious. To execute query methods, you don't need to provide an implementation at all. I suspect in your current setup the custom implementation you have in PersonRepositoryImpl "overrides" the query method and thus will be preferred on execution.
If you simply drop your implementation class, Spring Data will automatically execute the query for you on invocation.
Generally speaking, custom implementation classes are only needed for functionality you cannot get through other means (query methods, Querydsl intergration etc.).
I have gotten into a problem with my project. I am using a generic repository with structure map together with Fluent NHibernate. Everything works rather well, but when it comes to transactions and session management I have really no clue what to do. I have looked around for answers but I cant really find anything that fit my needs.
What I do in my application is that I let structure map instantiate a repository class when it gets a request for it, like so:
internal class RepositoryRegistry : Registry
{
public RepositoryRegistry()
{
For<IRepository<User>>().Use<Repository<User>>();
For<IRepository<Tasks>>().Use<Repository<Tasks>>();
}
}
internal class NHibernateRegistry : Registry
{
public NHibernateRegistry()
{
For<ISessionFactory>()
.Singleton()
.Use(() => new NHibernateSessionFactory().GetSessionFactory());
For<ISession>()
.Singleton()
.Use(x => x.GetInstance<ISessionFactory>().OpenSession());
}
}
public interface IRepository<T>
{
T GetById(int id);
void SaveOrUpdate(T entity);
IList<T> GetAll();
IQueryable<T> Linq();
void Add(T entity);
}
Edit: I have concluded what I need. I wan't to use the unit of work pattern along with structure map, but I also want to have some kind of repository wrapper which can be accessed through a unit of work.
Thanks,
James Ford
I think that you are looking for the Unit Of Work pattern, where the transaction life time is controlled by a unit of work that you inject into the Repostories/Services.
See this answer for a sample implementation of a UoW with NHibernate and StructureMap.
Edit:
Provided you have implemented a Unit of Work and a generic repository you would basically use them by:
1) Mapping them in structure map:
c.For(typeof(IRepository<>)).Use(typeof(Repository<>));
c.For<IUnitOfWork>().Use<UnitOfWork>();
2) Having the Controller accept a Repository(or a Service encapsulating the repository; this approach is often preferred) and the UnitOfWork:
public class MyController
{
public MyController(IRepository<MyEntity> repository, IUnitOfWork uow)
{
_repository = repository;
_unitOfWork = uow;
}
}
This of course also requires that you have created a custom ControllerFactory.
3) Using the Unit of Work and Repository in the controller action:
public ViewResult MyAction(MyEntity entity)
{
_repository.Save(entity);
_unitOfWork.Commit();
return View();
}
I need to use GWT with a service-based domain layer - not beans with DAOs. Is the GWT 2.1 architecture with MVP and RequestFactory fitted for this? Or should I stay with RPC?
Thanks
GWT 2.1.1 adds a Locator and ServiceLocator mechanism to allow you to control how the RequestFactory server code obtains references to entities and service object instances.
For example, you can declare code like
class MyService.class {
// Note that this is not a static method
public void doSomething() {....};
}
class MyServiceLocator implements ServiceLocator {
public Object getInstance(Class<?> clazz) {
// Or use Guice, Spring, whatever provides instances of MyService
return new MyService();
}
}
interface MyRequestFactory extends RequestFactory {
#Service(value=MyService.class, locator=MyServiceLocator.class)
interface ServiceRequest extends RequestContext {
Request<Void> doSomething();
}
ServiceRequest myService();
}
If you need even more control over how RequestFactory interacts with your server domain objects or service code, you can inject instances of ServiceLayerDecorator into the service layer.