spring service is not autowired in main class - java

Here is my SourceRepository class which does not override the autogenerated general findAll() which returns Iterable
package com.infostream.repositories;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.PagingAndSortingRepository;
import com.infostream.models.Source;
public interface SourceRepositoryImpl extends PagingAndSortingRepository<Source, Long>{
Page<Source> findAll(Pageable pageRequest);
}
Here is my service class:
package com.infostream.services;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;
import com.infostream.models.Source;
import com.infostream.repositories.SourceRepositoryImpl;
#Component
public class SourcesService {
#Autowired
private SourceRepositoryImpl sourceRepository;
public PageImpl<Source> getPaginatedSources(Pageable pageRequest) {
Page<Source> searchResultPage = sourceRepository.findAll(pageRequest);
return new PageImpl<Source>(searchResultPage.getContent(), pageRequest, searchResultPage.getTotalElements());
}
public Iterable<Source> getAllSources() {
return sourceRepository.findAll();
}
}
Here is my main class which i run as a Java application.
package com.infostream.services;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.infostream.consumers.RssArticleConsumer;
import com.infostream.models.Article;
import com.infostream.models.Source;
import com.infostream.producers.RssXmlProducer;
public class HarvestService {
private static BlockingQueue<Article> article_queue = new ArrayBlockingQueue<Article>(10);
#Autowired
private static SourcesService sourcesService;
public static void main(String[] args) throws InterruptedException {
Iterable<Source> sources = sourcesService.getAllSources();
/*
for(Source s : sources) {
System.out.println(s.getUrl());
}
Thread t1 = new Thread(new RssXmlProducer(sources.iterator().next(), article_queue));
Thread t2 = new Thread(new RssArticleConsumer(article_queue));
t1.start();
t2.start();
t1.join();
t2.join();
*/
}
}
The sourcesService variable is null, i see the Autowiring is not working but i do not know why. Is it because i am running the HarvestService file as a Java Application by right clicking on the file in the package explorer and clicking run as java application?

i had the same problem also, #Autowired was not working in the main class
What i did was to get a reference to the ApplicationContext, then use it to get the sourcesService as a bean
have rewrote your class as below
package com.infostream.services;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
// adedd import file
import org.springframework.context.ApplicationContext;
import com.infostream.consumers.RssArticleConsumer;
import com.infostream.models.Article;
import com.infostream.models.Source;
import com.infostream.producers.RssXmlProducer;
#SpringBootApplication // added this here
public class HarvestService
{
private static BlockingQueue<Article> article_queue = new ArrayBlockingQueue<Article>(10);
#Autowired
private static SourcesService sourcesService;
ApplicationContext context; // added this here
public static void main(String[] args) throws InterruptedException {
// added this - get reference to application context
context = SpringApplication.run(HarvestService.class, args);
// added this - get the object via the context as a bean
sourcesService = (SourcesService) context.getBean("sourcesService");
Iterable<Source> sources = sourcesService.getAllSources();
/*
for(Source s : sources) {
System.out.println(s.getUrl());
}
Thread t1 = new Thread(new RssXmlProducer(sources.iterator().next(),article_queue));
Thread t2 = new Thread(new RssArticleConsumer(article_queue));
t1.start();
t2.start();
t1.join();
t2.join();
*/
}
}

are you using spring boot?
looks like your HarvestService class needs #SpringBootApplication and add thid in main function
SpringApplication.run(HarvestService.class, args);
and make sure you have the right dependency in your maven/gradle.
hope it helps

You have to implement CommandLineRunner and put your code inside the method run, because spring need to load all the components and with the normal main it is not going to work
#Override
public void run(String... args) throws Exception {
main(args);
}
SpringApplication.run main method

Used modelmapper dependency (2.4.4) .Use #RequiredArgsConstructor and modelmapper method with #Bean annotation on main class. The bean that to be initialize should be final.

Related

How Spring's Cacheable Annotation can work for class initailized through new Keyword. (In a Class Constructor, initialized through Bean)

In our service, we are initializing a bean (say "A") and that internally constructing a CacheableService Object by using - new CacheableService(). And as I know spring's #Cacheable annotations won't work on class method if the class is initialized using "new" Keyword.
Then what is an alternative or a way to cache method response?
Scenario :
<bean class="com.package.src.A"/>
public class A {
Map<String, CacheableService> map;
public CacheableService2() {
map = new HashedMap();
map.put("a", new CacheableService());
}
}
import org.springframework.cache.annotation.Cacheable;
public class CacheableService {
#Cacheable(value = "entityCount", key = "#criteria.toString()")
public int someEntityCount(final String criteria) {
System.out.println("Inside function : " + criteria);
return 5;
}
}
Here is a minimum example which demonstrates caching using Spring Boot. The code for the examples below can be found here.
Go to https://start.spring.io/ and create a new Spring Boot project. Make sure to include "Spring cache abstraction" which results in this entry being added to your pom:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
Add the #EnableCaching annotation to your application:
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
#EnableCaching
#SpringBootApplication
public class CacheableApplication {
public static void main(String[] args) {
SpringApplication.run(CacheableApplication.class, args);
}
}
Your service:
package com.example;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
#Service
public class CacheableService {
#Cacheable(value = "entityCount")
public int someEntityCount(final String criteria) {
System.out.print(String.format("Inside function: %s", criteria));
return 5;
}
}
Class A:
package com.example;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
#Component
public class A {
private CacheableService cacheableService;
public A(#Autowired CacheableService cacheableService) {
this.cacheableService = cacheableService;
}
public int getEntityCount(String criteria) {
return cacheableService.someEntityCount(criteria);
}
}
And then here is a test that demonstrates that the caching is working. As you can see in the test a.getEntityCount("foo") is being called twice, but in standard out we only see "Inside function: foo" being printed once. Therefore we have verified that the second call resulted in the cache being used to produce the result.
package com.example;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import static org.junit.jupiter.api.Assertions.assertEquals;
#SpringBootTest
class CacheableTest {
private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
#Autowired
private A a;
#BeforeEach
public void init() {
System.setOut(new PrintStream(outContent));
}
#Test
public void testCaching() {
a.getEntityCount("foo");
a.getEntityCount("foo");
assertEquals("Inside function: foo", outContent.toString());
}
}
EDIT:
If you want to move the cache outside of the Spring lifecycle and manually manage it then I would recommend using Caffeine. Here is the same example but now without any Spring involved.
Your service:
package com.example.withoutspring;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import java.util.concurrent.TimeUnit;
public class CaffeineCachingService {
private LoadingCache<String, Integer> entityCountCache = Caffeine.newBuilder()
.expireAfterAccess(5, TimeUnit.MINUTES)
.build(key -> someEntityCount(key));
public int cachedEntityCount(final String criteria) {
return entityCountCache.get(criteria);
}
private int someEntityCount(final String criteria) {
System.out.print(String.format("Inside function: %s", criteria));
return 5;
}
}
Class B:
package com.example.withoutspring;
public class B {
private CaffeineCachingService cacheableService;
public B() {
cacheableService = new CaffeineCachingService();
}
public int getEntityCount(String criteria) {
return cacheableService.cachedEntityCount(criteria);
}
}
And the same test but without Spring:
package com.example.withoutspring;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class CaffeineCacheableTest {
private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
private B b = new B();
#BeforeEach
public void init() {
System.setOut(new PrintStream(outContent));
}
#Test
public void testCaching() {
b.getEntityCount("foo");
b.getEntityCount("foo");
assertEquals("Inside function: foo", outContent.toString());
}
}
Obviously you need to tune the cache to perform how you want it so probably evicting the cached values after 5 minutes is not what you want but if you visit the Caffeine Github page you will see a lot of detailed examples how to configure the cache to meet your use-case.
Hope this helps!

Which is simpliest way to "threadify" a springboot application?

I start in java / springboot and I want to distribute an export function (initially a single class managed by SpingApplication), in several small classes performing an export chunk executed simultaneously.
/*
Here is my initial application class setted conventionally according to SpringBoot practice ...
Which works but it's too long
*/
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
#SpringBootApplication
public class Application {
public static Logger logger = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Exporter.class, args);
Exporter exporter = ctx.getBean(Exporter.class);
exporter.main(args);
}
}
/* The runnable classe in Exporter.java*/
package moteur;
import config.ClauseWhereConfig;
import config.FtpConfig;
import config.PigeExportHighcoConfig;
import config.Sql2oConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
#Configuration
#EnableAutoConfiguration
#Import({ ExportSession.class})
public class Exporter {
#Autowired
private ExportSession currentExport;
public static Logger logger = LoggerFactory.getLogger(Exporter.class);
public void main(String[] args) {
run(args);
}
public void run(String[] args) {
/*do some stuff ... */
}
/*
Then I tried this :
Each exporter instance is supposed to make a piece of "select from" original (as you know with the keyword limit <from>, <to>
*/
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.annotation.EnableAsync;
#SpringBootApplication
#EnableAsync
public class Application {
public static Logger logger = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Exporter.class, args);
Exporter exporter1 = ctx.getBean(Exporter.class);
Exporter exporter2 = ctx.getBean(Exporter.class);
exporter1.setName("exporter1");
exporter2.setName("exporter2");
exporter1.start();
exporter2.start();
}
}
/* The Exporter class now extends Thread object */
#Configuration
#EnableAutoConfiguration
#EnableAsync
#Import({ ExportSession.class, Sql2oConfig.class, ClauseWhereConfig.class, FtpConfig.class, PigeExportHighcoConfig.class})
public class Exporter extends Thread {
#Autowired
private ExportSession currentExport;
public static Logger logger = LoggerFactory.getLogger(Exporter.class);
public void main(String[] args) {
run(args);
}
public void run(String[] args) {
logger.info(getName() + "---- >: Is running" ) ;
}
This foolish attempt that of course doesn't work :
Exception in thread "main" java.lang.IllegalThreadStateException
at java.lang.Thread.start(Thread.java:708)
at moteur.Application.main(Application.java:27)
In fact i'm loking for a solution for a small autonomous batch treatment
have you got this ?

subclasses of abstract class object is null when using autowired

I have these classes. when I debug I see that the spring creates the service object in constructor and called the constructors in both classes but when I want to use the fields, they are null. What's the problem?! (type1Processor, type2Processor and type3Processor are null)
import com.vali.ReactiveSocketServer.service.ReceivedDataService;
import org.springframework.stereotype.Component;
public abstract class Processor {
public ReceivedDataService receivedDataService;
public Processor(ReceivedDataService receivedDataService) {
this.receivedDataService = receivedDataService;
}
public abstract void readStream(String stream);
}
and this is its subclass
import com.vali.ReactiveSocketServer.model.ReceivedData;
import com.vali.ReactiveSocketServer.service.ReceivedDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
#Component
public class Type1Processor extends Processor {
#Autowired
public Type1Processor(ReceivedDataService receivedDataService) {
super(receivedDataService);
}
#Override
public void readStream(String stream) {
System.out.println("readStream "+ getClass().getSimpleName() + "-" + stream);
receivedDataService.add(new ReceivedData(stream.getBytes()));
}
}
and this is its usage:
import com.vali.ReactiveSocketServer.processor.Processor;
import com.vali.ReactiveSocketServer.processor.Type1Processor;
import com.vali.ReactiveSocketServer.processor.Type2Processor;
import com.vali.ReactiveSocketServer.processor.Type3Processor;
import com.vali.ReactiveSocketServer.receivers.AppServer;
import com.vali.ReactiveSocketServer.socket.ClientHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.util.HashMap;
import java.util.Map;
#SpringBootApplication
public class ReactiveSocketServerApplication {
private AppServer appServer;
#Autowired
Type1Processor type1Processor;
#Autowired
Type2Processor type2Processor;
#Autowired
Type3Processor type3Processor;
public static void main(String[] args) {
SpringApplication.run(ReactiveSocketServerApplication.class, args);
ReactiveSocketServerApplication reactiveSocketServerApplication = new ReactiveSocketServerApplication();
reactiveSocketServerApplication.Start();
}
public void Start(){
appServer = AppServer.getInstance();
Map<Integer, Processor> processorMap = new HashMap<>();
processorMap.put(7001, type1Processor);
processorMap.put(7002, type2Processor);
processorMap.put(7003, type3Processor);
appServer.initialize(processorMap);
new ClientHandler(7001, 1000);
new ClientHandler(7002, 5000);
}
}
You are instantiating ReactiveSocketServerApplication yourself.
So spring can't inject the #Autowired annotated beans, because the instance was created outside of it's life cycle.
Remove this completly:
ReactiveSocketServerApplication reactiveSocketServerApplication = new ReactiveSocketServerApplication();
reactiveSocketServerApplication.Start();
And annotate your Start() with #PostConstruct:
#PostConstruct
public void Start() { ... }
You are missing #Component in the abstract class ReceivedDataService.
This mean when you create the subclases using :
#Autowired
public Type1Processor(ReceivedDataService receivedDataService) {
super(receivedDataService);
}
Can't inject ReceivedDataService and get the default value(null)

Field in com.XXX required a bean of type that could not be found

I'm working on Spring over Hibernate project an i'm only in the beginning.
I'm tryng to hav a SpringBootApplication which writes to MsSql some LogEntries objects.
I have some different packages:
here is the classes:
LogEntryFacadeImpl.class :
package com.tradingSystem.dataAccess;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.tradingSystem.entity.LogEntry;
#Service
public class LogEntryFacadeImpl implements LogEntryFacade{
#Autowired
private LogEntryDAO logEntryDao;
#Transactional
#Override
public Long addLogEntry(LogEntry log) {
return this.logEntryDao.save(log).getId();
}
#Override
public LogEntry getLogEntry(Long logId) {
return this.logEntryDao.findOne(logId);
}
}
LogEntryDAO.class:
package com.tradingSystem.dataAccess;
import org.springframework.data.jpa.repository.JpaRepository;
import com.tradingSystem.entity.LogEntry;
public interface LogEntryDAO extends JpaRepository<LogEntry, Long> {
}
and I use this class as tester:
TestApplication.class:
package com.testings;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import com.tradingSystem.dataAccess.LogEntryFacade;
import com.tradingSystem.entity.LogEntry;
#SpringBootApplication
#ComponentScan({"com.tradingSystem" })
public class TestApplication implements CommandLineRunner{
#Autowired
private LogEntryFacade logEntryFacade;
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
LogEntry log = new LogEntry(552266, "Testing of log entry save",
new Date(System.currentTimeMillis()),
new Date(System.currentTimeMillis()));
System.err.println(log);
Long id = logEntryFacade.addLogEntry(log);
LogEntry log2 = logEntryFacade.getLogEntry(id);
System.err.println(log2);
}
}
wher i run this as application i get this message in console:
APPLICATION FAILED TO START
Description:
Field logEntryDao in com.tradingSystem.dataAccess.LogEntryFacadeImpl required a bean of type 'com.tradingSystem.dataAccess.LogEntryDAO' that could not be found.
Action:
Consider defining a bean of type 'com.tradingSystem.dataAccess.LogEntryDAO' in your configuration.
I put the #ComponentScan({"com.tradingSystem" }) annotation in the tester as you can see. however, still get this message.
(when I didnt use any packages separation, everything works fine...)
Please help me solve this
Thanks
You should add #Repository annotation above your Repository interface.
Optionally you can add it like #Repository(value="logEntryRepository")
the default scan path is package of #SpringBootApplication class, so you must declare three scan path, but it's seems like that you missing two scan config, you need add
#EnableJpaRepositories(basePackages = "com.tradingSystem.dataAccess")
#EntityScan(basePackages = "com.tradingSystem.entity")
#ComponentScan(basePackages = "com.tradingSystem.dataAccess")
to the TestApplication class

Spring-Data-Rest Validator

I have been trying to add spring validators to a spring-data-rest project.
I followed along and setup the "getting started" application via this link: http://spring.io/guides/gs/accessing-data-rest/
...and now I am trying to add a custom PeopleValidator by following the documents here:
http://docs.spring.io/spring-data/rest/docs/2.1.0.RELEASE/reference/html/validation-chapter.html
My custom PeopleValidator looks like
package hello;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
public class PeopleValidator implements Validator {
#Override
public boolean supports(Class<?> clazz) {
return true;
}
#Override
public void validate(Object target, Errors errors) {
errors.reject("DIE");
}
}
...and my Application.java class now looks like this
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;
#Configuration
#EnableJpaRepositories
#Import(RepositoryRestMvcConfiguration.class)
#EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Bean
public PeopleValidator beforeCreatePeopleValidator() {
return new PeopleValidator();
}
}
I would expect that POSTing to the http://localhost:8080/people URL would result in an error of some kind since the PeopleValidator is rejecting everything. However, no error is thrown, and the validator is never called.
I have also tried manually setting up the validator as shown in section 5.1 of the spring-data-rest documentation.
What am I missing?
So it appears that the before/after "save" events only fire on PUT and PATCH. When POSTing, the before/after "create" events fire.
I tried it the manual way again using the configureValidatingRepositoryEventListener override and it worked. I'm not sure what I'm doing differently at work than here at home. I'll have to look tomorrow.
I sure would love to hear if others have suggestions on why it wouldn't work.
For the record, here is what the new Application.java class looks like.
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.rest.core.event.ValidatingRepositoryEventListener;
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;
#Configuration
#EnableJpaRepositories
#Import(RepositoryRestMvcConfiguration.class)
#EnableAutoConfiguration
public class Application extends RepositoryRestMvcConfiguration {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
protected void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener validatingListener) {
validatingListener.addValidator("beforeCreate", new PeopleValidator());
}
}
Looks like the feature is currently not implemented (2.3.0), unluckily there are no constants for the event names otherwise the solution below would not be that fragile.
The Configuration adds all properly named Validator beans to ValidatingRepositoryEventListener using the right event.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.rest.core.event.ValidatingRepositoryEventListener;
import org.springframework.validation.Validator;
#Configuration
public class ValidatorRegistrar implements InitializingBean {
private static final List<String> EVENTS;
static {
List<String> events = new ArrayList<String>();
events.add("beforeCreate");
events.add("afterCreate");
events.add("beforeSave");
events.add("afterSave");
events.add("beforeLinkSave");
events.add("afterLinkSave");
events.add("beforeDelete");
events.add("afterDelete");
EVENTS = Collections.unmodifiableList(events);
}
#Autowired
ListableBeanFactory beanFactory;
#Autowired
ValidatingRepositoryEventListener validatingRepositoryEventListener;
#Override
public void afterPropertiesSet() throws Exception {
Map<String, Validator> validators = beanFactory.getBeansOfType(Validator.class);
for (Map.Entry<String, Validator> entry : validators.entrySet()) {
EVENTS.stream().filter(p -> entry.getKey().startsWith(p)).findFirst()
.ifPresent(p -> validatingRepositoryEventListener.addValidator(p, entry.getValue()));
}
}
}
A bit of a stab in the dark - I've not used spring-data-rest. However, after having a read of the tutorial you're following, I think the problem is that you need a PersonValidator not a PeopleValidator. Rename everything accordingly:
PersonValidator
package hello;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
public class PersonValidator implements Validator {
#Override
public boolean supports(Class<?> clazz) {
return true;
}
#Override
public void validate(Object target, Errors errors) {
errors.reject("DIE");
}
}
Application
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;
#Configuration
#EnableJpaRepositories
#Import(RepositoryRestMvcConfiguration.class)
#EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Bean
public PersonValidator beforeCreatePersonValidator() {
return new PersonValidator();
}
}
Another way of doing it is to use annotated handlers as specified here
http://docs.spring.io/spring-data/rest/docs/2.1.0.RELEASE/reference/html/events-chapter.html#d5e443
Here is an example of how to use annotated handlers:
import gr.bytecode.restapp.model.Agent;
import org.springframework.data.rest.core.annotation.HandleBeforeCreate;
import org.springframework.data.rest.core.annotation.HandleBeforeSave;
import org.springframework.data.rest.core.annotation.RepositoryEventHandler;
import org.springframework.stereotype.Component;
#Component
#RepositoryEventHandler(Agent.class)
public class AgentEventHandler {
public static final String NEW_NAME = "**modified**";
#HandleBeforeCreate
public void handleBeforeCreates(Agent agent) {
agent.setName(NEW_NAME);
}
#HandleBeforeSave
public void handleBeforeSave(Agent agent) {
agent.setName(NEW_NAME + "..update");
}
}
Example is from github edited for brevity.

Categories

Resources