I ran the getting started guide (http://www.axonframework.org/axon-2-quickstart-guide/) and it works fine.
I tried to replace the FileSystemEventStore with JpaEventStore, but it doesn't store any event.
Here is my configuration:
public static void main(String[] args) {
CommandBus commandBus = new SimpleCommandBus();
CommandGateway commandGateway = new DefaultCommandGateway(commandBus);
//EventStore eventStore = new FileSystemEventStore(new SimpleEventFileResolver(new File("./events")));
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory( "cqrsworkshop" );
EntityManager entityManager = entityManagerFactory.createEntityManager();
SimpleEntityManagerProvider entityManagerProvider = new SimpleEntityManagerProvider(entityManager);
EventStore eventStore = new JpaEventStore(entityManagerProvider);
EventBus eventBus = new SimpleEventBus();
EventSourcingRepository<ToDoItem> repository = new EventSourcingRepository<ToDoItem>(ToDoItem.class, eventStore);
repository.setEventBus(eventBus);
AggregateAnnotationCommandHandler.subscribe(ToDoItem.class, repository, commandBus);
AnnotationEventListenerAdapter.subscribe(new ToDoEventHandler(), eventBus);
final String itemId = UUID.randomUUID().toString();
commandGateway.send(new CreateToDoItemCommand(itemId, "Need to do this"));
commandGateway.send(new MarkCompletedCommand(itemId));
entityManagerFactory.close();
}
<persistence-unit name="cqrsworkshop">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<!-- JPA Event Store -->
<class>org.axonframework.eventstore.jpa.DomainEventEntry</class>
<class>org.axonframework.eventstore.jpa.SnapshotEventEntry</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:h2:~/test" />
<property name="javax.persistence.jdbc.user" value="sa" />
<property name="javax.persistence.jdbc.password" value="" />
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect " />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
ATM to use JPA with Axon requires Spring. The only implementation provided for Axon TransactionManager is SpringTransactionManager which requires an instance of org.springframework.orm.jpa.JpaTransactionManager. See JpaEventStore and resource local transactions: quite old but seems still valid.
By Spring I mean not only Spring-orm but also Spring-context and Spring-aspects. I haven't find out how to use JpaTransactionManager without all the Spring magic.
Two exemples:
a vaadin one
a console one (in Xtend but it's really Java like)
Related
I am trying to use Spring's ReloadableResourceBundleMessageSource for LocalValidatorFactoryBean so that when I update an error message it should reflect without requiring the server to be restarted. I am using Spring 4.1.4, hibernate-validator 4.3.2.Final.
Below are the code details -
context.xml -
<mvc:annotation-driven validator="validator" />
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>file:../conf/fileapplication</value> <!-- Messages here will override the below properties file-->
<value>/WEB-INF/application</value>
</list>
</property>
<property name="cacheSeconds" value="10"></property> <!-- Will check for refresh every 10 seconds -->
</bean>
<bean name="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="validationMessageSource">
<ref bean="messageSource"/>
</property>
</bean>
Model -
import org.hibernate.validator.constraints.NotBlank;
public class InputForm {
#NotBlank ( message = "{required.string.blank}")
String requiredString;
Controller -
#RequestMapping(value = "/check/string", method = RequestMethod.POST)
public String checkString(
#ModelAttribute("formModel") #Valid InputForm inputForm ,
BindingResult result, Model model, HttpServletResponse response,
HttpServletRequest request) {
if (result.hasErrors()) {
model.addAttribute("formModel", inputForm);
return "userInput";
}
// Do some backend validation with String
result.reject("string.not.valid",
"String is Invalid");
model.addAttribute("formModel", inputForm);
return "userInput";
}
application.properties (in /WEB_INF/ folder)
required.string.blank=Please enter the required string.
string.not.valid=Please enter a valid string.
fileapplication.properties (in /conf/ folder. Will override above file)
required.string.blank=You did not enter the required string. #Does not reflect when I change here
string.not.valid=You did not enter a valid string. #Reflects when I change here
Now the problem I am facing is, when I update "string.not.valid" in fileapplication.properties it reflects at runtime and I see the updated message. But when I update "required.string.blank" in fileapplication.properties it does not reflect at runtime.
Note that the overriding part is working fine for both messages upon application start up. But the "reloading" part is not working fine for "required.string.blank".
This is what I figured out based on my research - We need to create our own MessageInterpolator and add it as dependency to the validator instead of message source. Because when we add a messageSource as dependency, it is cached by default by the validator and any message reloads spring does won't take effect in the validator's cached instance of messageSource.
Below are the details:
In context.xml, add the custom MessageInterpolator as dependency to LocalValidatorFactoryBean instead of messageSource:
<mvc:annotation-driven validator="validator" />
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>file:../conf/fileapplication</value> <!-- Messages here will override the below properties file-->
<value>/WEB-INF/application</value>
</list>
</property>
<property name="cacheSeconds" value="10"></property> <!-- Will check for refresh every 10 seconds -->
</bean>
<bean name="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="messageInterpolator">
<ref bean="messageInterpolator"/>
</property>
</bean>
<bean name="messageInterpolator"
class="com.my.org.support.MyCustomResourceBundleMessageInterpolator">
<constructor-arg ref="messageSource" />
</bean>
Create your custom MessageInterpolator by extending Hibernate's org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator.
public class MyCustomResourceBundleMessageInterpolator extends
ResourceBundleMessageInterpolator {
public MyCustomResourceBundleMessageInterpolator(MessageSource messageSource)
{
// Passing false for the second argument
// in the super() constructor avoids the messages being cached.
super(new MessageSourceResourceBundleLocator(messageSource), false);
}
}
Model, Controller and properties file can be same as in the question.
I have a simple Spring MVC application that makes an Ajax call to a ReST service using the RestTemplate class. Some of the elements in the schema start with uppercase letters. The 2 elements (code, message) with lowercase letters cause no problems. The classes generated by JAXB have the #XmlElement annotation and name property. This seems to be ignored. I've read that the JaxbAnnotationIntrospector needs to be used but none of the changes make that take effect. See class below. I've tried adding a bean class definition for RestTemplate in the Spring config, adding an object mapper but nothing helps. See error on OTPRO element in first few lines of stack trace:
[4/18/16 9:52:43:988 EDT] 00000024 SystemErr R org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Unrecognized field "OTPRO" (class com.ssdr.rest.message.SSDRResponse), not marked as ignorable (7 known properties: "dt", "ot", "message", "otpro", "otphone", "code", "dtphone"])
at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream#4ccbe679; line: 4, column: 14] (through reference chain: com.ssdr.rest.message.SSDRResponse["OTPRO"]); nested exception is com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "OTPRO" (class com.ssdr.rest.message.SSDRResponse), not marked as ignorable (7 known properties: "dt", "ot", "message", "otpro", "otphone", "code", "dtphone"])
at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream#4ccbe679; line: 4, column: 14] (through reference chain: com.ssdr.rest.message.SSDRResponse["OTPRO"])
[4/18/16 9:52:44:019 EDT] 00000024 SystemErr R at org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.readInternal(MappingJackson2HttpMessageConverter.java:126)
[4/18/16 9:52:44:019 EDT] 00000024 SystemErr R at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:153)
[4/18/16 9:52:44:019 EDT] 00000024 SystemErr R at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:81)
JAXB generated class:
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for documentResponse complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType name="documentResponse">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="code" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="message" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="OTPRO" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="OT" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="OTPhone" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="DT" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="DTPhone" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "documentResponse", propOrder = {
"code",
"message",
"otpro",
"ot",
"otPhone",
"dt",
"dtPhone"
})
public class DocumentResponse {
#XmlElement(required = true)
protected String code;
#XmlElement(required = true)
protected String message;
#XmlElement(name = "OTPRO", nillable = true)
protected String otpro;
#XmlElement(name = "OT", nillable = true)
protected String ot;
#XmlElement(name = "OTPhone", nillable = true)
protected String otPhone;
#XmlElement(name = "DT", nillable = true)
protected String dt;
#XmlElement(name = "DTPhone", nillable = true)
protected String dtPhone;
...
Service class:
SSDRResponse resp = null;
RestTemplate restTemplate = new RestTemplate();
HttpEntity<SSDRRequest> httpRequest = new HttpEntity<SSDRRequest>(req, createHeaders());
resp = restTemplate.postForObject(SERVICE_URI, httpRequest, SSDRResponse.class);
Spring config:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
<context:annotation-config />
<!-- Scans the classpath of this application for #Components to deploy as beans -->
<context:component-scan base-package="com.ssdr" />
<!-- Configures the #Controller programming model -->
<mvc:annotation-driven />
<!-- Forwards requests to the "/" resource to the "index" view -->
<!--
<mvc:view-controller path="/" view-name="index" />
-->
<!-- Make webapp/resources directory accessible to web app -->
<mvc:resources location="/resources/" mapping="/resources/**" />
<!-- Resolves view names to protected .jsp resources within the context root directory -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<bean class="org.springframework.web.client.RestTemplate">
<property name="messageConverters">
<list>
<bean
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes" value="application/json" />
<property name="objectMapper">
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<property name="annotationIntrospector">
<bean
class="com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector" />
</property>
</bean>
</property>
</bean>
</list>
</property>
</bean>
<!-- <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<map>
<entry key="html" value="text/html"/>
<entry key="json" value="application/json"/>
</map>
</property>
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</list>
</property>
<property name="defaultViews">
<list>
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
<property name="prefixJson" value="true"/>
</bean>
</list>
</property>
</bean> -->
</beans>
NOTE: I do not want to simply ignore the upper case elements.
The solution was to use a combination of JacksonAnnotationIntrospector and JaxbAnnotationIntrospector. In this case Jackson was needed to recognize the #JsonIgnoreProperties and #JsonInclude annotations in the request. But Jackson always threw the "Unrecognized field" errors. JAXB could read the response with the uppercase fields but would not recognize the annotations on the request.
To use both introspectors the following code was added to the service class:
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
MappingJackson2HttpMessageConverter jaxMsgConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objMapper = new ObjectMapper();
/*
* Jackson introspector needed for #JsonIgnoreProperties and #JsonInclude annotations
* JAXB introspector is needed to handle the uppercase element names in the response
*/
AnnotationIntrospector primary = new JacksonAnnotationIntrospector();
AnnotationIntrospector secondary = new JaxbAnnotationIntrospector(TypeFactory.defaultInstance());
AnnotationIntrospector pair = AnnotationIntrospector.pair(primary, secondary);
objMapper.setAnnotationIntrospector(pair);
jaxMsgConverter.setObjectMapper(objMapper);
messageConverters.add(jaxMsgConverter);
SSDRResponse resp = null;
RestTemplate restTemplate = new RestTemplate();
// Set message converter with Jackson and JAXB introspectors in RestTemplate
restTemplate.setMessageConverters(messageConverters);
HttpEntity<SSDRRequest> httpRequest = new HttpEntity<SSDRRequest>(req, createHeaders());
resp = restTemplate.postForObject(SERVICE_URI, httpRequest, SSDRResponse.class);
To use only the JAXB introspector:
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
MappingJackson2HttpMessageConverter jaxMsgConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper jaxMapper = new ObjectMapper();
AnnotationIntrospector introspector = new JaxbAnnotationIntrospector(TypeFactory.defaultInstance());
jaxMapper.setAnnotationIntrospector(introspector);
jaxMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // ignore unknown properties
jaxMsgConverter.setObjectMapper(jaxMapper);
messageConverters.add(jaxMsgConverter);
My spring boot configuration (ready to use):
#Configuration
#EnableWebMvc
#EnableAutoConfiguration
#ComponentScan(basePackages = {"path.to.your.package"})
public class WebMvcConfig extends WebMvcConfigurerAdapter {
#Bean
public ObjectMapper objectMapper() {
ObjectMapper jacksonMapper = new ObjectMapper();
AnnotationIntrospector primary = new JacksonAnnotationIntrospector();
AnnotationIntrospector secondary = new JaxbAnnotationIntrospector(TypeFactory.defaultInstance());
AnnotationIntrospector pair = AnnotationIntrospector.pair(primary, secondary);
jacksonMapper.setAnnotationIntrospector(pair);
jacksonMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
return jacksonMapper;
}
#Bean
public RestTemplate getRestTemplate() {
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
MappingJackson2HttpMessageConverter jaxMsgConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = objectMapper();
jaxMsgConverter.setObjectMapper(objectMapper);
messageConverters.add(jaxMsgConverter);
HttpClientBuilder builder = HttpClientBuilder.create();
HttpClient httpClient = builder.build();
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
RestTemplate template = new RestTemplate(new BufferingClientHttpRequestFactory(factory));
template.setMessageConverters(messageConverters);
return template;
}
}
For my desktop application I need to change SQLite database connection in runtime (actually it is just "Open file" action).
Datasource is configured using Spring-JDBC.
1) Extend SingleConnectionDataSource to be able to change JDBC URL:
public class ChangeableSingleConnectionDataSource extends SingleConnectionDataSource {
public void updateUrl(String filePath) {
setUrl("jdbc:sqlite:" + filePath);
resetConnection();
}
}
2) Define dataSource in context.xml
<bean id="dataSource" class="package.ChangeableSingleConnectionDataSource" destroy-method="destroy">
<property name="driverClassName" value="org.sqlite.JDBC"/>
<property name="url" value="jdbc:sqlite:"/>
<property name="suppressClose" value="true"/>
</bean>
3) When you need to open a new database file just call
dataSource.updateUrl(newFile.getAbsolutePath());
I am currently using Spring MVC 3.x,
and using the freemarker view resolver.
Recently i have been wondering about the execution time that it takes for a view to translate into html before getting sent back as a response. I would like to do tunings if things are slow in this area, which is why i need some numbers.
In plain freemarker mode, i can actually do the simple System.currentTimeMillis() between these to find out the execution time :
long start = System.currentTimeMillis();
// this could be slow or fast depending on the caching used
Template temp = cfg.getTemplate(ftlName);
...
temp.process(model, myWriter); // depends on the writer
System.out.printf("done in %s ms", System.currentTimeMillis() - start);
But how do i do this when with spring mvc's freemaker view rendering ?
You might consider extending org.springframework.web.servlet.view.freemarker.FreeMarkerView and configuring FreeMarkerViewResolver with your custom logging view implementation.
Logging view implementation could look like this:
public class LoggingFreeMarkerView extends FreeMarkerView {
private static final transient Log log = LogFactory.getLog(LoggingFreeMarkerView.class);
#Override
protected void doRender(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
long start = System.currentTimeMillis();
super.doRender(model, request, response);
log.debug("Freemarker rendered " + request.getRequestURI() + " in " + (System.currentTimeMillis() - start) + " ms");
}
}
And wire the view resolver with new class:
<bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver" autowire="no">
<property name="viewClass" value="com.example.LoggingFreeMarkerView" />
<property name="cache" value="false" /> <!-- cache disabled for performance monitoring -->
<property name="prefix" value="" />
<property name="suffix" value=".ftl" />
<property name="contentType" value="text/html;charset=utf-8" />
<property name="exposeRequestAttributes" value="true" />
<property name="requestContextAttribute" value="base" />
</bean>
You are going to calculate just on server side merging template with data,Main problem is when freemarker executing on page ,As you know freemarker built on top of jsp page so you should bring code to jsp side to calculate execution time,
As my experience according to data size load time in freemarker is different.
if else condition also is too slow compare to jstl!
I can recommend thymeleaf for spring that allowing templates to be working prototypes on not xml style .
I've inherited a project and am trying to get a set of integration tests running against an in-memory h2 database. In order for them to pass some tables, relationships and reference data needs creating.
I can see the problem in that the script referenced in RUNSCRIPT is being executed multiple times and therefore generating Index "XXX_IDX" already exists errors and other violations. So is there a way to force the script to only be run once or do I need a external database? It seems that the script is run on every connection which I assume is by design.
properties file
my.datasource.url=jdbc:h2:mem:my_db;DB_CLOSE_DELAY=-1;MODE=Oracle;MVCC=TRUE;INIT=RUNSCRIPT FROM 'classpath:/create-tables-and-ref-data.sql'
XML config
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="url" value="${my.datasource.url}"/>
<!-- other properties for username, password etc... -->
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="myDataSource"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="myDataSource"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
many Java classes in the following pattern
#Component
public class SomethingDAOImpl implements SomethingDAO {
#Autowired
public SomethingDAOImpl(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
}
#Component
public class SomethingElseDAOImpl implements SomethingElseDAO {
#Autowired
public SomethingElseDAOImpl(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
}
With the default bean scope being singleton I thought this would just work, but I guess i'm missing something. Also, if I switch to an real Oracle instance that already has the tables and reference data set-up, the tests all pass.
In many cases, it is possible to write the SQL script so that no exceptions are thrown:
create table if not exists test(id int, name varchar(255));
create index if not exists test_idx on test(name);
I ended up using an alternative approach, as I could not write the SQL in a way that could be reapplied without error.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd">
<jdbc:initialize-database data-source="myDataSource" enabled="true" ignore-failures="ALL">
<jdbc:script location="classpath:create-and-alter-tables-first-then-add-test-data.sql" />
</jdbc:initialize-database>
</beans>
which is executed once at context initialization.
Note: other namespaces and beans omitted for brevity.