#Rollback(true) not working in spring boot 1.3.X - spring

I have updated my pom from spring-boot-starter-parent 1.2.5.RELEASE to 1.3.2.RELEASE.
The problem is that everything stay the same but all the test #Rollback(true) not working at all after migration.
#Transactional
#Rollback(true)
#Test
public void testRollBack() {
dao.saveToDb();
throw new RunTimeException();
}
Configaturation:
#Bean
#Primary
public PlatformTransactionManager txManager() {
return new DataSourceTransactionManager(dataSource());
}
It works perfectly in the same configuration and code and the only change is spring boot version. I cannot see that Transaction is being created in logs as suppose too
Anyone has a clue? Maybe a way to debug and understand what is the problem?
Thanks

TransactionTestExecutionListener has changed quite a lot between Spring Framework 4.1 (used by Spring Boot 1.2) and Spring Framework 4.2 (used by Spring Boot 1.3). It sounds like there's been a change in behaviour which I suspect probably wasn't intentional.
To fix your problem without renaming one of your beans, you need to tell the test framework which transaction manager to use. The easiest way to do that is via the #Transactional annotation:
#Transactional("txManager")
#Rollback(true)
#Test
public void testRollBack() {
dao.saveToDb();
throw new RunTimeException();
}

I have put spring on debug..
There is a problem/bug in the test framework or i don't understand the use correctly.
I checked the code of spring and saw this:
bf.getBean(DEFAULT_TRANSACTION_MANAGER_NAME, PlatformTransactionManager.class);
This happens when we have several transaction manager, instead of getting the bean marked by #Primary annotation spring try to get transaction manager that called "transactionManager".
The solution is just mark the bean in that name.. Tried to open issue to spring-test project but don't know where.. If anyone knows how please advise.
Thanks
EDIT: So the solution is eiether what i have wrote above or just name them transaction(#Transactional("myManager")) and use it in the test method signature

Related

instanciating SolrCrudRepository programmatically, without Spring Boot magic

I have a Spring Boot 2.4 project that is using spring-boot-starter-data-solr. Unfortunately, spring-boot-starter-data-solr is not supported anymore (see https://spring.io/projects/spring-data-solr#overview) , so I can't easily upgrade Spring Boot as I usually do for other projects.
However, I thought I would still try to upgrade my project and keep using the latest spring-boot-starter-data-solr I could get : maybe it's not supported anymore, but I am not making an extensive use of it, so maybe I can take advantage of latest Spring Boot features for a some more time, before there's really a breaking change and I really can't use spring-boot-starter-data-solr
So, I upgraded my project to Spring Boot 2.6.4 letting Spring BOM pull all the latest versions of all dependencies managed. Of course, it failed on spring-boot-starter-data-solr, so I had to declare the version explicitly :
implementation 'org.springframework.boot:spring-boot-starter-data-solr:2.4.13'
I fixed few other things, and my project compiles. However, at startup (and in some integration tests), I have a problem :
#Configuration
public class PersistenceConfig {
#Bean
public TicketRepository ticketRepository(SolrTicketEntityRepository solrTicketEntityRepository) {
return new TicketRepositoryImpl(solrTicketEntityRepository);
}
... some other beans..
}
with SolrTicketEntityRepository defined like below :
public interface SolrTicketEntityRepository extends SolrCrudRepository<TicketEntity, String> {
#Query("?0")
Page<TicketEntity> search(String searchText, Pageable pageable);
With Spring Boot 2.6, the SolrTicketEntityRepository doesn't get instanciated anymore, so I have a missing bean at startup. I've tried adding the #EnableSolrRepositories on PersistenceConfig, but it doesn't do anything.
is there a way to mimic Spring Boot magic, and trigger programmatically SolrTicketEntityRepository / SolrCrudRepository instanciation, to be able to start my application ?
or is it way too complicated, and as recommended here , should I implement the stuff myself with the core Solr libraries without Spring Boot's help (which would be the objective at some point anyway) ?

Spring Boot JPA CrudRepository

I'm working with Spring Boot + Spring Data JPA and facing this problem when trying to inject a class that extends CrudRepository:
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'topicRepository': Could not resolve
matching constructor (hint: specify index/type/name arguments for
simple parameters to avoid type ambiguities)
Repository Class:
public interface TopicRepository extends CrudRepository<Topic, Integer> {}
Service Class:
#Service
public class TopicService {
#Autowired
private TopicRepository topicRepository;
}
Any suggestions?
I was having the same issue, and I fixed it by switching Spring Boot versions. Changing the Spring Data JPA versions did nothing (this is where I assumed the bug would be), so I think there is a bug in Spring Boot version 1.5.1. I switched back to version 1.4.3 and the error was gone. I didn't try subsequent/different versions, so you may just have to experiment with your dependencies and their versions.
For the record, you can have your service class annotated with #Repository, it shouldn't make any difference. I've been setting these apps up the same way using the service/dao pattern, and it has never been too picky with the annotations. Hopefully this may help others whose Spring Boot development flow suddenly throws an error!
Which versions of spring-data-commons and spring-data-jpa are you using. I just ran into this using spring-data-commons 1.13.x with spring-data-jpa 1.10.x. Upgrading spring-data-jpa to 1.11.x fixed the issue for me.
I too had the same issue after updating Spring Boot to 1.5.4.
I am also using spring-data-envers, which was at version 1.0.4. Upgrading to 1.4.1 solved the problem.
I hope it helps someone :)
Make sure:
1) TopicRepository is annotated with #Repository.
2) You have the scanning packages configured:
<jpa:repositories base-package="mypkg.repositories"></jpa:repositories>
Had the same issue on 1.5.2. Upgrading to 1.5.5 solved the problem.
You can use Applicationcontext to inject repository to this reference topicRepository..
You just declare applicationcontext in #rest controller class
Same like topicRepository by using annotation. Then you pass this to the service class which should take parms through constructor.
Ex-
public TopicService(Applicationcontext ctx) {this.topicRepository =context.getBean(TopicRepository.class);
}

Using the Grails Cache Plugin on Normal Spring Service Bean

i have some standard Spring #Service classes in a separate jar lib that use the standard #Cacheable Spring annotation, in a Spring boot project i declare the dependency, configure a CacheManager and just works!
i try to do the same in a Grails 3.1 project but with no luck!
i discover that https://github.com/grails-plugins/grails-cache require to use its 'proprietary' #Cacheable annotation:
http://grails-plugins.github.io/grails-cache/3.0.x/api/grails/plugin/cache/Cacheable.html
As workaround i FORKED some Service just to use the Grails #Cacheable and it's working but i'd like to have a single #Service that works under grails or not!
I have misconfigured something, it doesn't behave the same way, but i can't figure out what is it!
i'd like to share this jar lib between spring only & grails projects, but so far i can't make caching work, unless i forked the service calsses under
grails-app/services directory & used 'proprietary' #Cacheable annotation;
i try to remove the plugin and configure the bean and the cache in:
/GPsGrails3/grails-app/init/gpsgrails3/Application.groovy
with the org.springframework.context.annotation.Bean annotation:
#Primary
#Bean
public ConcurrentMapCacheManager concurrentMapCacheManager() {
return new ConcurrentMapCacheManager();
}
#Bean
public SignatureService signatureService() {
SignatureService _signatureService = new SignatureService();
return _signatureService;
}
i put signatureService under grails-app/services directory:
/GPsGrails3/grails-app/services/it/finmatica/ifw/impl/SignatureService.groovy
Maybe i have to configure my beans in:
/GPsGrails3/grails-app/conf/spring/resources.groovy ?
i have to use the version 4 of the plugin?
compile "org.grails.plugins:cache:4.+"
I am not sure what the question is but you don't have to use the Grails #Cacheable annotation. If you want to use the Spring one in a Grails app, you can, and it will behave in the same way that it would if you weren't using Grails. You don't even need the plugin in order to do that.

Integrate Mongeez with Spring Boot and Spring Data MongoDB

I want to integrate Mongeez with my Spring Boot application and was wondering how to properly run Mongeez during application startup. Mongeez suggests creating a MongeezRunner bean. However, the challenge is to run Mongeez before any of the Spring Data initialization is happening, specifically, before the MongoTemplate instance is created. This is crucial because there might be changes in the database that prevent the application to start at all (e.g. changing index definitions).
My current approach is to provide the MongoTemplate bean myself, running Mongeez before creating it:
#Bean
public MongoTemplate mongoTemplate(Mongo mongo, MongoDbFactory mongoDbFactory,
MongoConverter converter) throws IOException {
// make sure that Mongeez runs before Spring Data is initialized
runMongeez(mongo);
return new MongoTemplate(mongoDbFactory, converter);
}
private void runMongeez(Mongo mongo) throws IOException {
Mongeez mongeez = new Mongeez();
mongeez.setMongo(mongo);
mongeez.setDbName(mongodbDatabaseName);
mongeez.setFile(new ClassPathResource("/db/migrations.xml"));
mongeez.process();
}
It works, but it feels like a hack. Is there any other way to do this?
After taking a look at Spring Boot's source code, it turns out that this problem isn't anything new. The FlywayAutoConfiguration for example has to make sure that Flyway (a migration tool for SQL-based databases) runs before any EntityManagerFactory beans are created. To achieve this the auto-configuration registers a BeanFactoryPostProcessor that dynamically makes every EntityManagerFactory bean depend on the Flyway bean, thus forcing Spring to create the Flyway bean first.
I solved my problem by creating a Spring Boot starter with a similar auto-configuration for Mongeez: mongeez-spring-boot-starter.

reload in play framework 2.2 java giving exceptions when used with spring data jpa and hibernate

I am using Play Framework 2.2, Hibernate as JPA provider (4.2.8.Final), Spring (4.0.1.RELEASE) and Spring Data JPA (1.4.3.RELEASE).
I am using spring to instantiate to the controllers and using context:component-scan at the application load time to collect and configure all the required dependencies(repositories etc).
The way I have configured spring with play framework is
public class Global extends GlobalSettings {
private ApplicationContext applicationContext;
#Override
public void onStart(Application arg0) {
String configLocation = Play.application().configuration().getString("spring.context.location");
applicationContext = new ClassPathXmlApplicationContext(configLocation);
}
#Override
public <A> A getControllerInstance(Class<A> type) throws Exception {
return applicationContext.getBean(type);
}
}
and relevant section in application-context.xml is
Everything works extremely good when application loads for the first time. How ever as soon as I make any changes either in views or controllers and application reloads, Spring Data Jpa breaks and complains that my models are not of managed types.
Caused by: java.lang.IllegalArgumentException: Not an managed type: class models.User
Though it is not a problem in general, restarts works fine, I would really appreciate if someone can provide any inputs to reload the applicationContext completely on play reload.
I've had the same problem. Changing Spring Data JPA 1.4.3.RELEASE to 1.4.2.RELEASE solved it. I didn't have time to look further into the problem, so I don't know what is the cause.
This project is a good starting point: https://github.com/typesafehub/play-spring-data-jpa but it uses 1.3 version of Spring Data JPA.

Resources