Save LocaTime via SpringData to MongoDB - mongodb

I try to save a LocalTime (joda) field to the MongoDB with SpringData using spring-boot-starter-parent (org.springframework.boot 1.2.3.RELEASE) and get a StackOverflowError.
The StackOverflowError is in BeanWrapper in the method
public <S> S getProperty(PersistentProperty<?> property, Class<? extends S> type)
Stacktrace:
http-nio-8080-exec-2#5509 daemon, prio=5, in group 'main', status: 'RUNNING'
at org.springframework.data.mapping.model.BeanWrapper.getProperty(BeanWrapper.java:120)
at org.springframework.data.mapping.model.BeanWrapper.getProperty(BeanWrapper.java:100)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$3.doWithPersistentProperty(MappingMongoConverter.java:419)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$3.doWithPersistentProperty(MappingMongoConverter.java:412)
at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:307)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:412)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writePropertyInternal(MappingMongoConverter.java:511)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$3.doWithPersistentProperty(MappingMongoConverter.java:424)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$3.doWithPersistentProperty(MappingMongoConverter.java:412)
at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:307)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:412)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writePropertyInternal(MappingMongoConverter.java:511)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$3.doWithPersistentProperty(MappingMongoConverter.java:424)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$3.doWithPersistentProperty(MappingMongoConverter.java:412)
at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:307)...

Adding these two Converters to the CustomConversions fix the problem.
#Configuration
public class MongoConfiguration extends AbstractMongoConfiguration {
#Override
protected String getDatabaseName() {
return "databasename";
}
#Override
public Mongo mongo() throws Exception {
return new MongoClient("localhost");
}
#Override
public CustomConversions customConversions() {
List<Converter<?, ?>> converters = new ArrayList<>();
converters.add(new LocalTimeToStringConverter());
converters.add(new StringToLocalTimeConverter());
return new CustomConversions(converters);
}
}
public class LocalTimeToStringConverter implements Converter<LocalTime, String> {
#Override
public String convert(LocalTime localTime) {
return localTime.toString();
}
}
public class StringToLocalTimeConverter implements Converter<String, LocalTime> {
#Override
public LocalTime convert(String s) {
return LocalTime.parse(s);
}
}

Related

ArangoDB own converters

How can I add my own ArangoDB configuration converter.
An example of a converter.
public class HTMLConverter {
private static final boolean HTML_DESCRIPTION_IS_PRESENT = ClassUtils.isPresent("com.b.k.api.domain.extend.HTML", null);
public static Collection<Converter<?, ?>> getConvertersToRegister() {
if (!HTML_DESCRIPTION_IS_PRESENT) {
return Collections.emptySet();
}
final List<Converter<?, ?>> converters = new ArrayList<>();
converters.add(HtmlToStringConverter.INSTANCE);
converters.add(StringToHtmlConverter.INSTANCE);
return converters;
}
public enum HtmlToStringConverter implements Converter<HTML, String> {
INSTANCE;
#Override
public String convert(final HTML source) {
return source == null ? null : source.getXml();
}
}
public enum StringToHtmlConverter implements Converter<String, HTML> {
INSTANCE;
#Override
public HTML convert(final String source) {
return source == null ? null : new HTML(source);
}
}
}
The reproduction of my converters looks like this:
public class BKArangoCustomConverters extends CustomConversions {
private static final StoreConversions STORE_CONVERSIONS;
static {
final Collection<Converter<?, ?>> converters = new ArrayList<>();
converters.addAll(XMLConverter.getConvertersToRegister());
converters.addAll(HTMLConverter.getConvertersToRegister());
STORE_CONVERSIONS = StoreConversions.of(SimpleTypeHolder.DEFAULT, converters);
}
protected BKArangoCustomConverters(Collection<?> converters) {
super(converters);
}
}
I am asked how can I add new converters to the ArangoDB configuration using the builder "com.arangodb.ArangoDB.Builder" in the extension class "com.arangodb.springframework.config.AbstractArangoConfiguration".
You have to override the method customConversions() from AbstractArangoConfiguration in your configuration class and add your converters there.
public CustomConversions customConversions() {
Collection<Converter<?, ?>> converters = new ArrayList<>();
converters.addAll(XMLConverter.getConvertersToRegister());
converters.addAll(HTMLConverter.getConvertersToRegister());
return new ArangoCustomConversions(converters);
}
or you replace the ArangoCustomConversions with our own clasn class BKArangoCustomConverters.
public CustomConversions customConversions() {
return new BKArangoCustomConverters(Collections.emptyList());
}

Spring Boot - Bean named entityManagerFactory

I am trying to make a simple Spring Boot application generated with jHipster to get from a postgresql a list of articles from a postreSQL database and display it using a rest controller, but when i run it i get
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in org.adi.security.DomainUserDetailsService required a bean named 'entityManagerFactory' that could not be found.
Action:
Consider defining a bean named 'entityManagerFactory' in your configuration.
But the thing is that that `DomainUserDetailsService is something generated by jhipster which stopped working after i added my classes. So i will write below my classes:
Article Entity:
package org.adi.domain;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="articles")
public class Article implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="article_id")
private int articleId;
#Column(name="title")
private String title;
#Column(name="category")
private String category;
public int getArticleId() {
return articleId;
}
public void setArticleId(int articleId) {
this.articleId = articleId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
}
ArticleDAO (Repository):
#Transactional
#Repository
public class ArticleDAO implements IArticleDAO {
#PersistenceContext
private EntityManager entityManager;
#Override
public Article getArticleById(int articleId) {
return entityManager.find(Article.class, articleId);
}
#SuppressWarnings("unchecked")
#Override
public List<Article> getAllArticles() {
String hql = "FROM Article as atcl ORDER BY atcl.articleId DESC";
return (List<Article>) entityManager.createQuery(hql).getResultList();
}
#Override
public void createArticle(Article article) {
entityManager.persist(article);
}
#Override
public void updateArticle(Article article) {
Article artcl = getArticleById(article.getArticleId());
artcl.setTitle(article.getTitle());
artcl.setCategory(article.getCategory());
entityManager.flush();
}
#Override
public void deleteArticle(int articleId) {
entityManager.remove(getArticleById(articleId));
}
#Override
public boolean articleExists(String title, String category) {
String hql = "FROM Article as atcl WHERE atcl.title = ? and atcl.category = ?";
int count = entityManager.createQuery(hql).setParameter(1, title)
.setParameter(2, category).getResultList().size();
return count > 0 ? true : false;
}
}
ArticleService:
#Service
public class ArticleService implements IArticleService {
#Autowired
private IArticleDAO articleDAO;
#Override
public Article getArticleById(int articleId) {
Article obj = articleDAO.getArticleById(articleId);
return obj;
}
#Override
public List<Article> getAllArticles(){
return articleDAO.getAllArticles();
}
#Override
public synchronized boolean createArticle(Article article){
if (articleDAO.articleExists(article.getTitle(), article.getCategory())) {
return false;
} else {
articleDAO.createArticle(article);
return true;
}
}
#Override
public void updateArticle(Article article) {
articleDAO.updateArticle(article);
}
#Override
public void deleteArticle(int articleId) {
articleDAO.deleteArticle(articleId);
}
}
and finally my REST controller:
#Controller
#RequestMapping("user")
#CrossOrigin(origins = {"http://localhost:4200"})
public class ArticleController {
#Autowired
private IArticleService articleService;
#GetMapping("article")
public ResponseEntity<Article> getArticleById(#RequestParam("id") String id) {
Article article = articleService.getArticleById(Integer.parseInt(id));
return new ResponseEntity<Article>(article, HttpStatus.OK);
}
#GetMapping("all-articles")
public ResponseEntity<List<Article>> getAllArticles() {
List<Article> list = articleService.getAllArticles();
return new ResponseEntity<List<Article>>(list, HttpStatus.OK);
}
#PostMapping("article")
public ResponseEntity<Void> createArticle(#RequestBody Article article, UriComponentsBuilder builder) {
boolean flag = articleService.createArticle(article);
if (flag == false) {
return new ResponseEntity<Void>(HttpStatus.CONFLICT);
}
HttpHeaders headers = new HttpHeaders();
headers.setLocation(builder.path("/article?id={id}").buildAndExpand(article.getArticleId()).toUri());
return new ResponseEntity<Void>(headers, HttpStatus.CREATED);
}
#PutMapping("article")
public ResponseEntity<Article> updateArticle(#RequestBody Article article) {
articleService.updateArticle(article);
return new ResponseEntity<Article>(article, HttpStatus.OK);
}
#DeleteMapping("article")
public ResponseEntity<Void> deleteArticle(#RequestParam("id") String id) {
articleService.deleteArticle(Integer.parseInt(id));
return new ResponseEntity<Void>(HttpStatus.NO_CONTENT);
}
}
Did you create a Persistence Unit?
[Reference]=> https://docs.oracle.com/cd/E19798-01/821-1841/bnbrj/index.html
Once you already have the persistence-unit's tag defined you are able to create your entity manager like this:
private final String PERSISTENCE_UNIT_NAME = "PUName";
private EntityManagerFactory eMFactory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
EntityManager entityManager=eMFactory.createEntityManager();

return JSON in Spring MVC 4

I'm new to spring mvc and I wish to create a RESTful service.
I create a controller,maps a function to URL and when I try to access it instead of a JSON I receive a 406 error.
I guess there is some trouble with the configuration(Java configuration) but I can't find what it is.
here is my WebConfig:
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.yated.web.controller")
public class WebConfig {
}
here is my WebInitializer:
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { WebConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
and here is the controller:
#RestController
public class EventsController {
#RequestMapping(value = "/events")
public List<String> getEvents()
{
List<String> list = new ArrayList<String>();
list.add("Event1");
list.add("Event2");
return list;
}
}
and as I said when I try to access:
http://localhost:8181/web/events
or
http://localhost:8181/web/events.json
I get http error 406
Any ideas?

Map that extends TreeMap deserialized as empty map on client

I need to pass a map with a custom field to client.
just TreeMap works fine, but not descendants of TreeMap. If I change TreeMap to HashMap, it also works fine.
GWT 2.5.1
public class MyMap extends TreeMap<String, String> {
public String s;
public MyMap() {
}
public MyMap(String s) {
this.s = s;
}
}
public class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService {
#Override
public Map<String, String> testSelfMap() {
Map<String, String> c = new MyMap("abc");
c.put("k", "v");
return c;
}
}
#RemoteServiceRelativePath("greet")
public interface GreetingService extends RemoteService {
Map<String, String> testSelfMap();
}
public interface GreetingServiceAsync {
void testSelfMap(AsyncCallback<Map<String, String>> async);
}
public class HW implements EntryPoint {
GreetingServiceAsync serv = GWT.create(GreetingService.class);
public void onModuleLoad() {
serv.testSelfMap(new AsyncCallback<Map<String, String>>() {
#Override
public void onSuccess(Map<String, String> result) {
System.out.println(result.get("k"));
}
#Override
public void onFailure(Throwable caught) {
caught.printStackTrace();
}
});
}
}

Junit to test restful service

I have written a junit to test my rest service offline.The junit for my restful controller extends AbstractControllerTestSupport which is used to create the dispatcherservletinstance.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(loader=MockWebContextLoader.class, locations={"/rest-servlet- test.xml"})
public abstract class AbstractControllerTestSupport extends TestCase {
private static DispatcherServlet dispatcherServlet;
....
public static DispatcherServlet getServletInstance() {
if(null == dispatcherServlet) {
dispatcherServlet = new DispatcherServlet() {
protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) {
return MockWebContextLoader.getInstance();
}
};
System.out.println("dispatcher:"+dispatcherServlet.getContextConfigLocation()+":"+dispatcherServlet.getWebApplicationContext());
try {
dispatcherServlet.init(new MockServletConfig());
} catch (ServletException se) {
System.out.println("Exception"+se.getMessage());
}
}
return dispatcherServlet;
}
Following is my loader class.
public class MockWebContextLoader extends AbstractContextLoader {
public static final ServletContext SERVLET_CONTEXT = new MockServletContext(
"/mHealthAPIs", new FileSystemResourceLoader());
private final static GenericWebApplicationContext webContext = new GenericWebApplicationContext();
protected BeanDefinitionReader createBeanDefinitionReader(
final GenericApplicationContext context) {
return new XmlBeanDefinitionReader(context);
}
public final ConfigurableApplicationContext loadContext(
final String... locations) throws Exception {
SERVLET_CONTEXT.setAttribute(
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
webContext);
webContext.setServletContext(SERVLET_CONTEXT);
createBeanDefinitionReader(webContext).loadBeanDefinitions(locations);
AnnotationConfigUtils.registerAnnotationConfigProcessors(webContext);
webContext.refresh();
webContext.registerShutdownHook();
return webContext;
}
public static WebApplicationContext getInstance() {
return webContext;
}
protected String getResourceSuffix() {
return "-context.xml";
}
the test runs fine with spring version 3.0 .However if I shift to spring 3.2.x it gives me following error "The type MockWebContextLoader must implement the inherited abstract method SmartContextLoader.loadContext(MergedContextConfiguration)" .This is because in 3.2.2 "AbstractContextLoader" implements "SmartContextLoader" .
Can you provide me with the work around?
Got the solution:I changed the MockWebContextLoader class as follows.
public class MockWebContextLoader extends AbstractContextLoader {
public static final ServletContext SERVLET_CONTEXT = new MockServletContext(
"/mHealthAPIs", new FileSystemResourceLoader());
private final static GenericWebApplicationContext webContext = new GenericWebApplicationContext();
protected BeanDefinitionReader createBeanDefinitionReader(
final GenericApplicationContext context) {
return new XmlBeanDefinitionReader(context);
}
#Override
public ApplicationContext loadContext(MergedContextConfiguration arg0)
throws Exception {
SERVLET_CONTEXT.setAttribute(
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
webContext);
webContext.setServletContext(SERVLET_CONTEXT);
createBeanDefinitionReader(webContext).loadBeanDefinitions(
arg0.getLocations());
AnnotationConfigUtils.registerAnnotationConfigProcessors(webContext);
webContext.refresh();
webContext.registerShutdownHook();
return webContext;
}
public static WebApplicationContext getInstance() {
return webContext;
}
protected String getResourceSuffix() {
return "-context.xml";
}
public final ConfigurableApplicationContext loadContext(
final String... locations) throws Exception {
return null;
}
}