Import own enum converter - java

I have a class which contains enum property.
public class Car{
private UserAction action;
//getters setters
}
And I want to save/read it from/to Mongo db. I am using Spring framework.
SpringConfig.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/data/mongo
http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<mongo:mongo host="127.0.0.1" port="27017" />
<mongo:db-factory dbname="dbName" />
<bean id="mappingContext"
class="org.springframework.data.mongodb.core.mapping.MongoMappingContext" />
<bean id="defaultMongoTypeMapper"
class="org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper">
<constructor-arg name="typeKey"><null/></constructor-arg>
</bean>
<bean id="mappingMongoConverter"
class="org.springframework.data.mongodb.core.convert.MappingMongoConverter">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
<constructor-arg name="mappingContext" ref="mappingContext" />
<property name="typeMapper" ref="defaultMongoTypeMapper" />
</bean>
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
<constructor-arg name="mongoConverter" ref="mappingMongoConverter" />
</bean>
<!--CODE BELOW CASES PROBLEMS-->
<mongo:mapping-converter id="mappingConverter">
<mongo:custom-converters>
<mongo:converter>
<bean class="myapp.mongo.converters.UserActionReadConverter"/>
</mongo:converter>
<mongo:converter>
<bean class="myapp.mongo.converters.UserActionWriteConverter"/>
</mongo:converter>
</mongo:custom-converters>
</mongo:mapping-converter>
</beans>
UserActionReadConverter.java
package myapp.mongo.converters;
import myapp.model.UserAction;
import com.mongodb.DBObject;
import org.springframework.core.convert.converter.Converter;
public class UserActionReadConverter implements Converter<DBObject, UserAction> {
public UserAction convert(DBObject source) {
String val = (String) source.get("value");
return (val.equals("PROCESSED_BY_USER" ) ? UserAction.PROCESSED_BY_USER : UserAction.UNPROCESSED_BY_USER);
}
}
UserActionWriteConverter.java
package myapp.mongo.converters;
import myapp.model.UserAction;
import org.springframework.core.convert.converter.Converter;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
public class UserActionWriteConverter implements Converter<UserAction, DBObject> {
public DBObject convert(UserAction userAction) {
DBObject dbo = new BasicDBObject();
dbo.put("value", userAction.toString());
return dbo;
}
}
operations initialisation
...
ApplicationContext ctx = new GenericXmlApplicationContext("SpringConfig.xml");
this.operations = (MongoOperations) ctx.getBean(beamName);
...
I have no idea, how to map converters into config .xml properly. It returns me error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.validation.beanvalidation.LocalValidatorFactoryBean#0': Invocation of init method failed; nested exception is javax.validation.ValidationException: Unable to create a Configuration, because no Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath.
The second question is. I want to convert simple enum, to do that I use a "supporting identificator" value. Can I transform enum without using it, that data in database will be stores as {car.userAction : "data value" } instead of {car.value.userAction : "data value" } .Thanks.

Missing validator library.
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.3.Final</version>
</dependency>

Related

Spring Data MongoDB <mongo:auditing/> cause IllegalArgumentException: Unsupported entity Could not determine IsNewStrategy

I upgrade my spring-data-mongodb (using maven) version to 1.9.5.RELEASE. (using MongoClient instead of Mongo).
My Session document class contains #LastModifiedDate annotation.
After the upgrade, i got java.lang.IllegalArgumentException: Unsupported entity com...Session! Could not determine IsNewStrategy.
If i remove from the configuration i don't get the error but it doesn't save the modifiedDate.
All the solutions I found related to MongoDB configuration using annotations and not xml file.
How can i solve this?
Maven dependencies:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.9.5.RELEASE</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.9.5</version>
</dependency>
Spring MongoDB configuration contain :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/context classpath:org/springframework/context/factory/xml/spring-context-3.0.xsd
http://www.springframework.org/schema/data/mongo classpath:org/springframework/data/mongo/factory/xml/spring-mongo-1.8.xsd
http://www.springframework.org/schema/beans classpath:org/springframework/beans/factory/xml/spring-beans-3.1.xsd
http://www.springframework.org/schema/util classpath:org/springframework/util/factory/xml/spring-util-3.0.xsd">
<bean class="com.....core.CascadingMongoEventListener"/>
<bean class="com.....core.DataEventListener"/>
<mongo:auditing/>
<mongo:mongo-client id="mongo" host="${host}" port="${port}">
<mongo:client-options connections-per-host="100"
connect-timeout="30000"
max-wait-time="15000"
socket-keep-alive="true"
socket-timeout="60000" />
</mongo:mongo-client>
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongo" ref="mongo" />
<constructor-arg name="databaseName" value="${dbName}"/>
<property name="writeConcern">
<util:constant static-field="com.mongodb.WriteConcern.SAFE" ></util:constant>
</property>
</bean>
<mongo:repositories base-package="com.....daos" mongo-template-ref="mongoTemplate">
</mongo:repositories>
<context:component-scan base-package="com.....services"></context:component-scan>
<!-- translate any MongoExceptions thrown in #Repository annotated classes -->
<context:annotation-config />
</beans>
My Document:
package com.....session;
import java.util.Date;
import java.util.UUID;
import org.joda.time.DateTime;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.LastModifiedDate;
#Document(collection = "session")
public class Session {
#Id
protected UUID id;
private DateTime creationDate;
#LastModifiedDate
private DateTime modifiedDate;
public Session() {}
//setters & getters
}
The trick is to share a MongoMappingContext between auditing and the MongoTemplate.
First replace:
<mongo:auditing/>
with:
<bean id="mappingContext" class="org.springframework.data.mongodb.core.mapping.MongoMappingContext" />
<mongo:auditing mapping-context-ref="mappingContext"/>
Then add a MongoDbFactory and a MongoConverter to your xml settings as follows:
<mongo:db-factory id="mongoDbFactory" mongo-ref="mongo" dbname="${dbName}"/>
<mongo:mapping-converter id="mongoConverter" db-factory-ref="mongoDbFactory" mapping-context-ref="mappingContext"/>
Last thing to do, is to inject the MongoConverter into the template. It supplies the MongoTemplate with the mapping context. You will have to use an alternate constructor for that.
Replace:
<constructor-arg name="mongo" ref="mongo" />
<constructor-arg name="databaseName" value="${dbName}"/>
with:
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
<constructor-arg name="mongoConverter" ref="mongoConverter"/>

Spring MVC Test setup fails on loading ApplicationContext.xml

Currently I'm trying to setup Spring MVC Controller testing for a school project I'm working on next to my job. Normally I program in php and frameworks like Laravel so this is pretty new for me. The problem is that I can't figure out how to solve the problem that keeps popping up on loading the ApplicationContext. Any help is appreciated.
Update:
I'm now told that test cases don't use a jndi ref in my app server. So this reference would fail on a test case, it runs fine on starting the application. Now I made a second file called servlet-test.xml (listed below) that uses a reference to the database on port 3306. I only use this file on tests not when starting up the application. But when I use this method I get Following error: Error creating bean with name 'productController': Injection of autowired dependencies failed. Any help is welcome as I'm struggling to setup MVC Controller tests for my school project. Other students I've been working with also are stuck with the same problem I am so I could help them out too.
I suspect the problem is the following, but I'm not sure how to solve this.
Error creating bean with name 'myDataSource' defined in URL
[file:web/WEB-INF/servlet.xml]: Invocation of init method failed;
nested exception is javax.naming.NamingException: Lookup failed for
'java:app/fotoproducent' ...
The Error Stack Trace
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in URL [file:web/WEB-INF/servlet.xml]: Cannot resolve reference to bean 'myDataSource' while setting bean property 'dataSource'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myDataSource' defined in URL [file:web/WEB-INF/servlet.xml]: Invocation of init method failed; nested exception is javax.naming.NamingException: Lookup failed for 'java:app/fotoproducent' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.url.pkgs=com.sun.enterprise.naming, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl} [Root exception is javax.naming.NamingException: Invocation exception: Got null ComponentInvocation ]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:107)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1456)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1197)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:973)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:750)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:121)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:100)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:250)
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContextInternal(CacheAwareContextLoaderDelegate.java:64)
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:91)
The Controller test i'm trying to run:
ProductController Test
package controller.tests.config;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration({"file:web/WEB-INF/servlet-test.xml", "file:web/WEB-INF/dispatcher-servlet.xml"})
public class ProductControllerTest {
#Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
#Before
public void setup() {
DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(this.wac);
this.mockMvc = builder.build();
}
#Test
public void testProductAction() throws Exception {
ResultMatcher ok = MockMvcResultMatchers.status().isOk();
ResultMatcher msg = MockMvcResultMatchers.model()
.attribute("msg", "Spring quick start!!");
MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/product");
this.mockMvc.perform(builder)
.andExpect(ok)
.andExpect(msg);
}
}
servlet.xml / applicationContext.xml file
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- module/package declarations -->
<context:component-scan base-package="Application" />
<context:component-scan base-package="Authentication" />
<context:component-scan base-package="Photo" />
<context:component-scan base-package="Product" />
<context:component-scan base-package="Organisation" />
<context:component-scan base-package="Login" />
<context:component-scan base-package="UI" />
<context:component-scan base-package="I18n" />
<context:component-scan base-package="Internationalization" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="myDataSource" class="org.springframework.jndi.JndiObjectFactoryBean" scope="singleton">
<property name="jndiName" value="java:app/fotoproducent" />
<property name="resourceRef" value="true" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
<property name="packagesToScan" value="*" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
</bean>
</property>
</bean>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
<mvc:resources mapping="/static/**" location="/static/"/>
<mvc:resources mapping="/resources/**" location="/resources/" />
<mvc:default-servlet-handler/>
<mvc:annotation-driven />
</beans>
Dispatcher-servlet.xml
<?xml version='1.0' encoding='UTF-8' ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMap ping"/>
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="index.html">indexController</prop>
<prop key="test.html">testController</prop>
</props>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/views/"
p:suffix=".jsp" />
<!--
The index controller.
-->
<bean name="indexController"
class="org.springframework.web.servlet.mvc.ParameterizableViewController"
p:viewName="index" />
<!--
The test controller.
-->
<bean name="testController"
class="org.springframework.web.servlet.mvc.ParameterizableViewController"
p:viewName="test" />
</beans>
Update 1: "DataSource Configuration"
This shows how the datasource is configured.
glassfish-resources.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
<resources>
<jdbc-connection-pool allow-non-component-callers="false" associate-with-thread="false" connection-creation-retry-attempts="0" connection-creation-retry-interval-in-seconds="10" connection-leak-reclaim="false" connection-leak-timeout-in-seconds="0" connection-validation-method="auto-commit" datasource-classname="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" fail-all-connections="false" idle-timeout-in-seconds="300" is-connection-validation-required="false" is-isolation-level-guaranteed="true" lazy-connection-association="false" lazy-connection-enlistment="false" match-connections="false" max-connection-usage-count="0" max-pool-size="32" max-wait-time-in-millis="60000" name="mysql_fotoproducent_rootPool" non-transactional-connections="false" pool-resize-quantity="2" res-type="javax.sql.DataSource" statement-timeout-in-seconds="-1" steady-pool-size="8" validate-atmost-once-period-in-seconds="0" wrap-jdbc-objects="false">
<property name="serverName" value="localhost"/>
<property name="portNumber" value="3306"/>
<property name="databaseName" value="fotoproducent"/>
<property name="User" value="root"/>
<property name="Password" value="password"/>
<property name="URL" value="jdbc:mysql://localhost:3306/fotoproducent?zeroDateTimeBehavior=convertToNull"/>
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
</jdbc-connection-pool>
<jdbc-resource enabled="true" jndi-name="app/fotoproducent" object-type="user" pool-name="mysql_fotoproducent_rootPool"/>
</resources>
Update 2: Additional Bean Config file (servlet-test.xml)
This results in beans not being loaded. Following error: Error creating bean with name 'productController': Injection of autowired dependencies failed
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:annotation-config/>
<mvc:annotation-driven />
<!-- module/package declarations -->
<context:component-scan base-package="Application" />
<context:component-scan base-package="Authentication" />
<context:component-scan base-package="Photo" />
<context:component-scan base-package="Product" />
<context:component-scan base-package="Organisation" />
<context:component-scan base-package="Login" />
<context:component-scan base-package="UI" />
<context:component-scan base-package="I18n" />
<context:component-scan base-package="Internationalization" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="myDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/fotoproducent?zeroDateTimeBehavior=convertToNull" />
<property name="username" value="root" />
<property name="password" value="password" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
<property name="packagesToScan" value="*" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
</bean>
</property>
</bean>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
<mvc:resources mapping="/static/**" location="/static/"/>
<mvc:resources mapping="/resources/**" location="/resources/" />
</beans>
Update 3: Additional Code for problem resolving
Product Controller
package Product.Controller;
import Product.Sevice.ProductService;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
#RequestMapping("/product")
public class ProductController {
#Autowired
protected ProductService service;
#RequestMapping(value = "", method = RequestMethod.GET)
public String productAction(ModelMap model)
{
model.put("productList", this.service.findAll());
return "product/overview";
}
}
Product Service
package Product.Sevice;
import Product.Entity.Product;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.transaction.Transactional;
import org.springframework.stereotype.Service;
#Service
public class ProductService {
#PersistenceContext
private EntityManager em;
#Transactional
public void insert(Product product)
{
// insert into database
// persist function is for NEW entities in database
this.em.persist(product);
}
#Transactional
public Product get(Integer id)
{
// this gets the entity from the database and returns it
return this.em.find(Product.class, (long) id);
}
#Transactional
public Product update(Product product)
{
// this updates the ExampleEntity in within the database
return this.em.merge(product);
}
#Transactional
public void remove(Integer id)
{
Product product = this.em.find(Product.class, (long) id);
product.delete();
// this updates the product in within the database
this.update(product);
}
#Transactional
public List<Product> findAll()
{
Query q = this.em.createNamedQuery("product.namedquery", Product.class);
return q.getResultList();
}
}
According to your stack trace when application context is initializing it still try to load wrong configuration files (servlet.xml), but should load servlet-test.xml. Please try to change your config locations with using path from root (src) folder, such as:
#ContextConfiguration({"file:src/main/web/WEB-INF/servlet-test.xml", "file:src/main/web/WEB-INF/dispatcher-servlet.xml"})
P.S Also you can try to move your config for tests (servlet-test.xml) to src/test/resources and load it from classpath: "classpath:servlet-test.xml". Also you can check this thread on stackoverflow: Spring #ContextConfiguration how to put the right location for the xml for extended discussion of similar problem.
You get an error which says that Spring IOC container fails to create and instantiate entityManagerFactory bean. Why?
That's another thing that your error exception mention. It fails to do so because it can't instantiate the myDataSource bean. Why?
According to your error message:
Lookup failed for 'java:app/fotoproducent'
It means that when IOC Spring container tried to create myDataSource bean, it failed to do so because it failed to set the jndiName with value of java:app/fotoproducent
Instead of using this:
<bean id="myDataSource" class="org.springframework.jndi.JndiObjectFactoryBean" scope="singleton">
<property name="jndiName" value="java:app/fotoproducent" />
<property name="resourceRef" value="true" />
</bean>
Replace it with:
<bean id="myDataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="your_driver_class_name" />
<property name="url" value="url_to_your_db" />
<property name="username" value="user_name_to_db" />
<property name="password" value="password_to_db" />
</bean>
My suggestion is to create a standard dataSource like mentioned on Spring docs above.
Now don't forget to replace the values for driver class name, url, user name, and password.
Here is an example from Spring docs, of how to define a data source for use of Hibernate ORM: http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#orm-hibernate

Iterating list in spring

Is there a way to iterate list or map in spring? I am not able to find any references for this online.
This is what I defined-
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">
<util:list id="myList" value-type="java.lang.String">
<value>foo</value>
<value>bar</value>
</util:list>
<bean id="bean1" class="com.StaticClass" factory-method="createObject">
<constructor-arg value="foo" />
</bean>
<bean id="bean2" class="com.StaticClass" factory-method="createObject">
<constructor-arg value="bar" />
</bean>
<bean id="myMap" class="java.util.HashMap">
<constructor-arg index="0" type="java.util.Map">
<map key-type="java.lang.Integer" value-type="java.lang.Float">
<entry key="foo" value-ref=bean1 />
<entry key="bar" value-ref=bean2 />
</map>
</constructor-arg>
</bean>
Instead of creating multiple bean objects, I want to iterate over this list and create a map, using following logic-
for (String m : myList) {
myMap.put(m, MyStaticFactory.createObject(m));
}
Can I do this in Spring?
How about using spring #Configuration (see explanation in this link) instead of spring XML?
#Configuration
public class MySpringContext {
#Bean(name="myMap")
public Map<String, StaticClass> getMyMapBean() {
// I'm not sure where you create 'm' but if that's a bean you can inject it to the class and use it.
for (String m : myList) {
myMap.put(m, MyStaticFactory.createObject(m));
}
}
}
#Configuration classes are a way to define your beans programatically instead of XMLs which gives you much more flexibility to do whatever you want.
Something like this maybe:
public class MyMapBean extends HashMap {
public MyMapBean(List<String> beanNames) {
for(name: beanNames) put(name, MyStaticFactory.createObject(name));
}
}
and then in application context:
<bean id="myMap" class="MyMapBean">
<constructor-arg index="0" value-ref="myList" />
</bean>

Still cannot access SoapHeader from endpoint

I am new to web services. After much googling and trying everything that's been posted about accessing the SoapHeader from endpoints, I still cannot get it to work. I'm getting the following error:
java.lang.IllegalStateException: No adapter for endpoint when adding
SoapHeader in the method signature of the handling method.
If I remove the SoapHeader parameter, I do not have any issues.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:sws="http://www.springframework.org/schema/web-services"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/web-services
http://www.springframework.org/schema/web-services/web-services-2.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />
<context:component-scan base-package="services" />
<sws:annotation-driven />
<sws:interceptors>
<bean id="validatingInterceptor"
class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor">
<property name="schema" value="/WEB-INF/schemas/cfPostBack2015.xsd" />
<property name="validateRequest" value="true"/>
<property name="validateResponse" value="true"/>
</bean>
<bean id="loggingInterceptor"
class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor" />
</sws:interceptors>
<sws:static-wsdl id="postBackService2015"
location="/WEB-INF/schemas/postBackService2015.wsdl" />
<bean id="marshaller" class="org.springframework.oxm.xmlbeans.XmlBeansMarshaller" />
<bean id="marshallingPayloadMethodProcessor"
class="org.springframework.ws.server.endpoint.adapter.method.MarshallingPayloadMethodProcessor">
<constructor-arg ref="marshaller"/>
<constructor-arg ref="marshaller"/>
</bean>
<bean id="defaultMethodEndpointAdapter"
class="org.springframework.ws.server.endpoint.adapter.DefaultMethodEndpointAdapter">
<property name="methodArgumentResolvers">
<list>
<ref bean="marshallingPayloadMethodProcessor" />
</list>
</property>
<property name="methodReturnValueHandlers">
<list>
<ref bean="marshallingPayloadMethodProcessor" />
</list>
</property>
</bean>
<bean id="postbackService"
class="PostBackServiceImpl" />
<bean id="postBackEndpoint"
class="PostBackEndpoint">
<property name="postBackService" ref="postBackService" />
</bean>
</beans>
Endpoint class:
package endpoints;
import javax.annotation.Resource;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
import org.springframework.ws.server.endpoint.annotation.RequestPayload;
import org.springframework.ws.server.endpoint.annotation.ResponsePayload;
import org.springframework.ws.soap.SoapHeader;
import PostBackService;
import cfPostBack.x2015.PostBackRequestDocument;
import cfPostBack.x2015.PostBackResponseDocument;
#Endpoint
public class PostBackServiceEndpoint {
private static final String TARGET_NAMESPACE =
"http://services/cfPostBack/2015/";
#Resource(name="postBackService")
private PostBackService postBackService;
#Autowired
public PostBackServiceEndpoint(PostBackService postBackService) {
this.postBackService = postBackService;
}
#PayloadRoot(localPart = "postBackRequest", namespace = TARGET_NAMESPACE)
#ResponsePayload
public PostBackResponseDocument getPostBackResponse(
#RequestPayload PostBackRequestDocument request, SoapHeader soapHeader)
throws Exception {
PostBackResponseDocument response =
postBackService.processPostBackRequest(request);
return response;
}
public void setPostBackService(PostBackService postBackService) {
this.postBackService = postBackService;
}
}
You probably need to add a org.springframework.ws.soap.server.endpoint.adapter.method.SoapMethodArgumentResolver bean to the methodArgumentResolvers list.
Actually, Andreas, you are right. Adding SoapMethodArgumentResolver bean to the methodArgumentResolvers list does work. I was trying to access the MessageContext in the endpoint instead of the SoapHeader. For the MessageContext, I added MessageContextMethodArgumentResolver.

spring data mongo repository is null

I am writing a standalone java program that call spring data repository for manging enities. I am using mongo db for persistence. I am following stackoverflow posts and some projects from github but when I run my program it fails since the repository is null. I am not expert in spring so it would be helpful if someone could show me the issue with the posted program.
Application-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/data/mongo
http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<mongo:mongo id="mongo" host="monopolyvm3" port="27017" />
<mongo:db-factory dbname="test" mongo-ref="mongo" />
<mongo:db-factory id="mongoDbFactory" dbname="cloud"
mongo-ref="mongo" />
<bean id="mappingContext" class="org.springframework.data.mongodb.core.mapping.MongoMappingContext" />
<bean id="defaultMongoTypeMapper"
class="org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper">
<constructor-arg name="typeKey"><null/></constructor-arg>
</bean>
<bean id="mappingMongoConverter" class="org.springframework.data.mongodb.core.convert.MappingMongoConverter">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
<constructor-arg name="mappingContext" ref="mappingContext" />
<property name="typeMapper" ref="defaultMongoTypeMapper" />
</bean>
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg ref="mongoDbFactory" />
<constructor-arg name="mongoConverter" ref="mappingMongoConverter" />
<property name="writeConcern" value="SAFE" />
</bean>
<context:component-scan base-package="com.xxxx"></context:component-scan>
<mongo:repositories base-package="com.xxxx.yyyy" />
Repository
public interface SlpRepository extends MongoRepository<Slp, Long> {
}
main program
public class App {
#Autowired
static
SlpRepository slpRepository;
public static void main(String[] args) {
ApplicationContext ctx = new GenericXmlApplicationContext("application-context.xml");
Slp slp = new Slp();
slp.setClientCount(100000L);
slp.setPolicyName("testing");
slp.setSlpName("slp_testing");
slpRepository.save(slp);
}
}
Object to store
------------------
#Document(collection="slps")
public class Slp implements Serializable {
private Long slpId;
private String slpName;
private String policyName;
private Long clientCount;
}
.....all getters and setters
JFYI..I tried to save object using mongotemplate and it works well.
The problem in this example is that you create the context in your App class but never get a handle to the repository from the application context. You cannot auto wire into the same class that holds the application context. What you can try is the get the instance of the repository from the context (i.e ctx.getBean(SlpRepository.class)).

Categories