Coder Social home page Coder Social logo

Comments (9)

quaff avatar quaff commented on May 31, 2024 1

Is there a way to get a bean into the fragment?

I think you want something with this declined PR.

But if spring-projects/spring-data-commons#3018 is accepted, you can do like this:

public interface BeanProvider {

	<T> T getBean(Class<T> clazz);

}

@RequiredArgsConstructor
public class BeanProviderImpl implements BeanProvider {

	private final BeanFactory beanFactory;

	@Override
	public <T> T getBean(Class<T> clazz) {
		return this.beanFactory.getBean(clazz);
	}

}


interface TestEntityRepository extends CrudRepository<TestEntity, Long>, BeanProvider {

	default void saveByEntityManager(TestEntity entity) {
		getBean(EntityManager.class).persist(entity);
	}

	default void saveBySelf(TestEntity entity) {
		getBean(TestEntityRepository.class).save(entity);
	}

}

from spring-data-jpa.

mp911de avatar mp911de commented on May 31, 2024

This is by design as the base repository class is parametrized using the entity information and EntityManager. JpaEntityInformation is specific to each repository and therefore, we cannot let the Spring context manage repository base class instances.

Taking a step back, what do you want to achieve that isn't achievable by using repository fragments?

from spring-data-jpa.

SledgeHammer01 avatar SledgeHammer01 commented on May 31, 2024

This is by design as the base repository class is parametrized using the entity information and EntityManager. JpaEntityInformation is specific to each repository and therefore, we cannot let the Spring context manage repository base class instances.

Taking a step back, what do you want to achieve that isn't achievable by using repository fragments?

Unless my understanding of repository fragments is incorrect (which is entirely possible), fragments seem to have a few requirements that didn't meet my needs:

  1. they are for a one off repository implementation rather then shared across multiple repositories?
  2. the location of the Impl class had to be in the same package? (which doesn't make sense if you want to apply to multiple repositories)

So, I went the extending the base class route.

Also, the main problem regarding the dependency injection I raised was due to the fact that the functionality I'm adding requires a per repository @ConfigurationProperties bean.

Basically, I'm trying to do something similar to the @EnableJpaRepositories functionality for multiple repositories.

DataSource1 -> Repo1
DataSource2 -> Repo2

Spring supports that scenario out of the box, but I'm going for:

DataSource1 + ConfigurationProperties1 -> Repo1
DataSource2 + ConfigurationProperties2 -> Repo2

I'm trying to follow the pattern that Spring lays out with auto injecting the data source, but since I can't enhance the annotation, I'm following the other Spring pattern of using a naming convention.

So, if the entity for the repo is called EntityOne, for example, I expect a configuration properties bean named entityOneRepoProperties.

To do this today, I have to have a custom factory and factory bean that @autowire the ApplicationContext and pass in the configuration properties through modifying this part:

Object repository =
    getTargetRepositoryViaReflection(
        information, **myProperties**, entityInformation, entityManager);

If I could have simply injected an ApplicationContext into the repo impl, I could have done that much easier.

from spring-data-jpa.

quaff avatar quaff commented on May 31, 2024

they are for a one off repository implementation rather then shared across multiple repositories?

I'm trying fix it by spring-projects/spring-data-commons#3018.

the location of the Impl class had to be in the same package? (which doesn't make sense if you want to apply to multiple repositories)

It's not true, but must be in basePackages.

from spring-data-jpa.

SledgeHammer01 avatar SledgeHammer01 commented on May 31, 2024

It's not true, but must be in basePackages.

Yeah, that's what I meant. That doesn't make sense if you want to share the fragment across multiple basePackages. Why not look in the same package as the interface as a secondary place? If you want it in a shared location, you need to use repositoryBaseClass which gets into the whole issue I mentioned.

from spring-data-jpa.

quaff avatar quaff commented on May 31, 2024

Yeah, that's what I meant. That doesn't make sense if you want to share the fragment across multiple basePackages. Why not look in the same package as the interface as a secondary place? If you want it in a shared location, you need to use repositoryBaseClass which gets into the whole issue I mentioned.

I agree, the PR will address it, would you take some time to verify?

from spring-data-jpa.

SledgeHammer01 avatar SledgeHammer01 commented on May 31, 2024

Yeah, that's what I meant. That doesn't make sense if you want to share the fragment across multiple basePackages. Why not look in the same package as the interface as a secondary place? If you want it in a shared location, you need to use repositoryBaseClass which gets into the whole issue I mentioned.

I agree, the PR will address it, would you take some time to verify?

I think that fix will make it easier for sharing fragments, but in my case, I don't think it will work since I need to get a bean in the implementation so had to use a full blown implementation and custom repositoryFactoryBeanClass.

Is there a way to get a bean into the fragment?

from spring-data-jpa.

mp911de avatar mp911de commented on May 31, 2024

You can take a more invasive approach by subclassing JpaRepositoryFactory and overriding getTargetRepository(…). For your case, you must provide AutowireCapableBeanFactory to your JpaRepositoryFactory subclass and call autowire on the resulting instance.

Finally, you need to configure @EnableJpaRepositories(repositoryFactoryBeanClass=YourJpaRepositoryFactoryBean.class) to stitch all the pieces together.

from spring-data-jpa.

SledgeHammer01 avatar SledgeHammer01 commented on May 31, 2024

You can take a more invasive approach by subclassing JpaRepositoryFactory and overriding getTargetRepository(…). For your case, you must provide AutowireCapableBeanFactory to your JpaRepositoryFactory subclass and call autowire on the resulting instance.

Finally, you need to configure @EnableJpaRepositories(repositoryFactoryBeanClass=YourJpaRepositoryFactoryBean.class) to stitch all the pieces together.

Yeah, that's what I ended up doing, but I didn't make it autowired, I just added it to the getTargetRepositoryViaReflection() call as an extra parameter since I "calculate" the desired bean name at runtime ala what Spring does.

Its definitely "invasive" :).

What @quaff proposed above should make things a lot easier.

from spring-data-jpa.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.