Spring Repositories with different profiles - spring-profiles

I have two different profiles and want to have two different repositories for this profiles. But it's repositories for one entity and it's just have different conditions in query.
I try to do this:
It's my base interface for repository:
public interface RepositoryBaseInterface extends CrudRepository<MyEntity, Long> {
List<MyEntity> getEntities();
}
And I have two profiles repository:
#Repository
#Profile("profile1)
public interface ProfileRepository extends RepositoryBaseInterface {
#Query("My query 1")
List<MyEntity> getEntities();
}
And another one:
#Repository
#Profile("profile2)
public interface ProfileRepository2 extends RepositoryBaseInterface {
#Query("My query 2")
List<MyEntity> getEntities();
}
I have class when I use this repository:
#Service
#RequiredArgConstructor
public class UseRepository{
RepositoryBaseInterface repository;
public List<MyEntity> getMyEntities() {
return repository.getEntities();
}
}
I have expected when I have one of two active profiles it will be chosen one of two ProfilesRepositories but I see that only RepositoryBaseInterface is using and I recieved error
Error creating bean with name RepositoryBeanInterface
IllegalArgumentException, No property getEntities found for type MyEntity
How can I fix this and use one or another repository in dependency of my active profile?

I understood my mistake. Our Base Interface ought to don't have any extends. But its implementation ought to.
So I have
public interface RepositoryBaseInterface {
List<MyEntity> getEntities();
}
And two Profile interface:
#Repository
#Profile("profile1)
public interface ProfileRepository extends RepositoryBaseInterface, CrudRepository<MyEntity, Long> {
#Query("My query 1")
List<MyEntity> getEntities();
}
#Repository
#Profile("profile2)
public interface ProfileRepository2 extends RepositoryBaseInterface, CrudRepository<MyEntity, Long> {
#Query("My query 2")
List<MyEntity> getEntities();
}

Related

hk2: why bind(X.class).to(X.class)

I am learning Java, but found the following piece of code. I am confused. What is bind(X.class).to(X.class); for?
import org.glassfish.hk2.utilities.binding.AbstractBinder;
public class ApplicationBinder extends AbstractBinder {
#Override
protected void configure() {
bind(X.class).to(X.class);
}
}
Thanks
You're configuring how you want your services to be discovered in the DI (dependency injection) system. bind(Service).to(Contract) is basically saying that you want to provide the Service as an injectable service, and want to "advertise" it as Contract. By "advertise", I mean what you want to be able to inject it as. For instance Service can be UserRepositoryImpl, while Contract can be UserRepository (interface). With this you would only be able #Inject UserRepository as that's what you advertise. The benefit of this is all the benefits that come with programming to an interface.
Example
interface UserRepository {
List<User> findAll();
}
class UserRepositoryImpl implements UserRepository {
#Override
public List<User> findAll() {
return Arrays.asList(new User("username"));
}
}
#Path("users")
class UserResource {
#Inject
private UserRepository repository;
#GET
public List<User> getUsers() {
return repository.findAll();
}
}
class JerseyApp extends ResourceConfig {
public JerseyApp() {
register(UserResource.class);
register(new AbstractBinder() {
#Override
public void configure() {
bind(UserRepositoryImpl.class)
.to(UserRepository.class);
}
});
}
}
Here the UserRepository is injected into the UserResource. When the DI system injects it, it will actually be the UserRepositoryImpl instance.
By doing that you are actually binding a new contract to a service.
bind(Service.class).to(Contract.class);
OR (binding a new contract to a service in Singleton)
bind(Service.class).to(Contract.class)..in(Singleton.class);

GraphRepository find method on 2nd level relationship

I am using spring-data-neo4j-4.2.0.RC1 and neo4j-ogm-core-2.1.0.jarHave the following domain objectsUser -> Role -> Priviledge
public class User extends BaseEntity{
private String firstName;
private String lastName;
#Relationship(type="ROLE")
private Role role;
}
#NodeEntity
public class Role extends BaseEntity{
private String name;
#Relationship(type="PRIVILEDGE")
private Priviledge priviledge;
}
#NodeEntity
public class Priviledge extends BaseEntity {
private String name;
}
public interface UserRepository extends GraphRepository<User> {
User findByRolePriviledgeName(String name);
}
I want to find all users that have a specific priviledge name. The above query worked with JPA and spring repository, but does not return expected result with GraphRepository. Not sure if this is a bug/not supported or I am doing something wrong
This is not supported in SDN- derived queries support only one level of nesting but yours uses two (Role, then Privilege).
You can write a custom #Query for this.

how to implement dependency injection in mvc?

I'm trying to implement dependency injection but i know how to implement the interface and repository of classes then i don't know what shall i do.
This my sample:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string LastName { get; set; }
}
This is my interface:
public interface IUser
{
IEnumerable<User> GetUsers();
void AddUser(User user);
void EditUser(User user);
void DeleteUser(int id);
User UserGetById(int id);
void Save();
}
This is my repository:
public class UserRepsitory:IUser
{
private _Context _context;
public UserRepsitory(_Context _context)
{
this._context = _context;
}
public IEnumerable<User> GetUsers()
{
return _context.User.ToList();
}
public void AddUser(User user)
{
_context.User.Add(user);
}
public void EditUser(User user)
{
_context.Entry(user).State = System.Data.Entity.EntityState.Modified;
}
public User UserGetById(int id)
{
return _context.User.Find(id);
}
public void Save()
{
_context.SaveChanges();
}
public void DeleteUser(int id)
{
var Search = _context.User.Find(id);
_context.User.Remove(Search);
}
}
And one of method in controller:
private IUser userRepsitory;
public UsersController()
{
this.userRepsitory = new UserRepsitory(new _Context());
}
public UsersController(IUser UserRepository)
{
this.userRepsitory = UserRepository;
}
public ActionResult Index()
{
return View(userRepsitory.GetUsers());
}
What is the next step?
The first thing is, get rid of the default constructor where we are hard coding the initialization of UserRepository ! We will do that in the dependency injection way.
public UsersController : Controller
{
private readonly IUser userRepsitory;
public UsersController(IUser UserRepository)
{
this.userRepsitory = UserRepository;
}
public ActionResult Index()
{
return View(userRepsitory.GetUsers());
}
}
Now we need something to tell the MVC framework which version/implementation of IUser should be used when the code runs. you can use any dependency injection frameworks to do that. For example, If you are in MVC 6, you can use the inbuilt dependency injection framework to do that. So go to your Startup class and in your ConfigureServices method, you can map an interface to a concrete implementation.
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IUser, UserRepository>();
}
}
If you are in a previous version of MVC, you may consider using any of the dependency injection frameworks available like Unity, Ninject etc.
It is pretty much same, you map an interface to a concrete implementation
Ninject
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IUser>().To<UserRepository>();
}
You do not need to put the mapping in a cs file. You can define that in a config file. For example, when you use Unity you can do something like this in your config file (web config or an external config file for unity configuration)
Unity
<alias alias="IUser" type="YourNamespace.IUser, YourAssemblyName" />
<register type="IUser" mapTo="YourNamespace.UseRepository, YourAssemblyName">
In order to create and configure your project with Spring DI(Dependency Feature) you must configure beans.
Create an xml file (if its not there) and add references to bean
In this xml file, provide references to the classes you want to inject. Example:
<bean id="Name of the JAVA Class" class="the Full path of the JAVA class"/>
And in your class where you are supposed to call the referencing class(above), calling procedure would be like :
#Controller
public class MyController {
private full.path.of.my.class.named.MyJavaClass _class;
#Autowired
private MyController (full.path.of.my.class.MyJavaClass class)
{
this._class= class;
}
}
Now say if you a function in MyJavaClass
public int sum(int x, int y){
return x+y;
}
Then without creating object of MyJavaClass you can inject like the following in your controller:
_class.Sum(10,15);
YOU DO NOT CREATE AN INSTANCE OF THIS CLASS.

multiple ejb injections which implement the same interface

i am very new to this ejb stuff. is there any possibility that in a single file i can have multiple injections based on some criteria.
for eg
public interface common(){
public void sayhello();
}
beanA
implements common()
beanB
implements common()
both are stateless beans
now i have a client which needs to trigger hello method based on some criteria. for eg. say based on console input if string contains A then beanA should be injected otherwise beanB.
Is there any possibility? and again my next question is , can i say this dynamic injection is not managed by container? if so how can i let container take the control? i need a sample code or atleast any tutorial ref.
thanks in advance!!
No, this is not really possible. You might be able to get close with a custom CDI scope that uses a thread local or session attribute, but I wouldn't recommend it. Instead, just inject a reference to both EJBs, and select the one to use as needed:
#EJB(beanName="BeanA")
Common beanA;
#EJB(beanName="BeanB")
Common beanB;
private Common getCommon(String input) {
return isBeanAInput(input) ? beanA : beanB;
}
you could do something like this:
public interfaces ICommon {
public void sayhello();
}
#Stateless
#LocalHome
public class BeanA implements ICommon {
public void sayhello() {
// say hallo
}
}
#Stateless
#LocalHome
public class BeanB implements ICommon {
public void sayhello() {
// say hallo
}
}
and here the CDI "client" which uses the EJB services
#Model
public void MyJSFControllerBean {
#Inject
private BeanA beanA;
#Inject
private BeanB beanB;
public String sayhello(final String input) {
if("a".equals(input)) {
beanA.sayhello();
} else {
beanB.sayhello();
}
return "success";
}
}
Or the other solution would be that you create a CDI producer to create this. but then you are mixing two different concepts. but i think it depends ou your concrete usecase.
dynamic injection does not exist! with #Produce and #Qualifier you can control the creation of the required CDI beans to inject. but this is only for CDI not for EJB.
here the CDI producer example:
public void ICommonProducer {
#EJB
private BeanA beanA;
#EJB
private BeanB beanB;
#Produces
public ICommon produce() {
final String input = "?????";
// but here you have the problem that must get the input from elsewhere....
if("a".equals(input)) {
beanA.sayhello();
} else {
beanB.sayhello();
}
}
}
#Model
public void MyJSFControllerBean {
#Inject
private ICommon common;
public String sayhello(final String input) {
common.sayhello();
return "success";
}
}
i have not teseted this code...

Resolving a Dependency with ServiceStack IoC Container

I have a repository that implements MongoRepository which uses generics I'm trying to register the type in the container so far this is what I got:
public override void Configure(Container container)
{
container.RegisterAutoWiredAs<UserRepository,
IUserRepository>();
//Trying to wireup the internal dependencies
container.RegisterAutoWiredType(
typeof(MongoRepository<>),
typeof(IRepository<>));
}
I tried RegisterAutoWiredAs<UserRepository> as well.
The problem is when I run the application I got the following error:
Error trying to resolve Service '{ServiceName}' or one of its
autowired dependencies
I guess because I have registered the repository without registering the mongoDB repository as a dependency.
As far as I know funq doesn't support generics, but I'm not sure if that's the same scenario with ServiceStack.
the repo has the following definition:
public class UserRepository
: MongoRepository<User>, IUserRepository
{
}
public interface IUserRepository : IRepository<User>
{
}
Edit:
This is the service definition, actually pretty basic!
public class MyService : Service {
private readonly IUserRepository _userRepository;
public MyService(IUserRepository userRepository)
{
_userRepository = userRepository;
}
public UserResponse Any(UserRequest userRequest)
{
//_userRepository.GetById(id)
}
}
DTOs:
public class UserRequest
{
public string Id { get; set; }
}
public class UserResponse
{
public User User { get; set; }
}
Funq works pretty intuitively, i.e. whatever you register you can resolve. So just make sure what you're trying to resolve, is the same thing as what you've registered.
There is no magic behavior in Funq, so this is an example of what doesn't work:
container.RegisterAutoWiredType(typeof(MongoRepository<>), typeof(IRepository<>));
If you want to be able to resolve MongoRepository<User> you need to register it, e.g:
container.RegisterAutoWiredAs<MongoRepository<User>,IUserRepository>();
Which you're then free to resolve like a normal dependency:
public class MyService : Service
{
private readonly IUserRepository _userRepository;
public MyService(IUserRepository userRepository)
{
_userRepository = userRepository;
}
}

Resources