I have an application that uses Spring+MyBatis and I have a Mapper interface to hold the SQL queries.
Mapper.java
package it.helloworld.mybatis;
import it.helloworld.dao.model.Numbers;
import java.util.List;
import org.apache.ibatis.annotations.Select;
public interface Mapper {
#Select("SELECT * FROM numbers")
List<Numbers> getNumbers();
}
I have used the MapperScannerConfigurer to use this Mapper as follows:
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="it.helloworld.ibatis" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory1" />
</bean>
I have used the name 'sqlSessionFactory1' because I have mutiple datasources in my application.
My question is:
I would like to change the interface to an XML file. Meaning I want to store my SQL query in an XML instead of an Interface. Can I configure MapperScannerConfigurer to do read SQL from an XML instead of an interface.? If yes, how.? If not, what should I use so as to make minimum code changes.?
Please check http://mybatis.github.io/spring/factorybean.html for more details on configuring your sqlSessionFactory1
The world has move on from MapperScannerConfigurer, then too let me answer this one. All you need in #MapperScan annotation.
Related
I'd like to use the Freemarker templating engine from within a controller's webscript to process some expression.
I've seen Alfresco provide the document.processTemplate("template content here") API.
The documentation says: "Executes a template from the repository against the current Document node"
Let's say I don't have any specific document to use, I just want to execute the templating engine and retrieve the output. What's the best way to do it?
Should I use some sort of temporary or "proxy" document? What's the easiest way to do so?
Not quite understandning what you are after here, I however think this is possible (not sure why anyone would like to do it though.)
You write your own class extending the BaseTemplateProcessorExtension, in that class you could write a method performing the stuff you want.
public class MyTemplateProcessorExtension extends BaseTemplateProcessorExtension {
public String myMethod(){
return "Hello World";
}
}
Declare it the following way in your spring config.
<bean id="templateHelper" parent="baseTemplateImplementation" class="my.alfresco.repo.template.TemplateHelper">
<property name="extensionName" value="templateHelper" />
</bean>
Then you can call it from your freemarker with:
${templateHelper.myMethod()}
The freemarker template calling "myMethod" should be a node in the repository (it should be possible to place it in the classpath as well, however I never had any success with this), since the processTemplate needs a nodeRef to the template itself.
Ok, please beware. I don't recommend this approach for anyone :)
I don't think it's possible to not use a document. So use a folder like data dictionary or create a dummy document with no content you always use.
The main purpose of alfresco is managing document.What kind of output you will produce without having value of any metadata of document in the template.This is the main reason behind this is not supported in alfresco, template engine is designed in such a way so that we can process any document.
I am trying to implement design time Unity configuration (e.g.: using app.config). I am struggling with the very example of how to use the tag the "configuring instances" section.
Their sample of run-time configuration is:
EmailService myEmailService = new EmailService();
myContainer.RegisterInstance<IMyService>(myEmailService);
but no equivalent design-time configuration given. If I do:
<container>
<instance type="IMyService" value="EmailService" />
</container>
I will naturally get a "TypeConverter cannot convert from System.String" exception. Am I supposed to create some sort of type converter merely so that I could declare an instance? Is there an easier way?
v2.1.1, joda module.
I can convert a json file to a pojo in a unit test using objectMapper.readValue(file, pojo .class);
However, when a Spring RESTTemplate client invokes the default json converter to convert an inputStream containing the domain object with Joda types (DateTime or LocalDate), it generates an error: objectMapper.readValue(httpInputMessage.getBody(), javaType)
com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of org.joda.time.DateTime out of START_OBJECT token
at Source: org.mortbay.jetty.HttpParser$Input#46a09b; line: 1, column: 752
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164)
at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:599)
at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:593)
at com.fasterxml.jackson.datatype.joda.deser.DateTimeDeserializer.deserialize(DateTimeDeserializer.java:51)
at com.fasterxml.jackson.datatype.joda.deser.DateTimeDeserializer.deserialize(DateTimeDeserializer.java:21)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:375)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:559)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObjectUsingNonDefault(BeanDeserializer.java:393)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:289)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:226)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:203)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:23)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:375)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeSetAndReturn(MethodProperty.java:106)
at com.fasterxml.jackson.databind.deser.BuilderBasedDeserializer.deserializeFromObject(BuilderBasedDeserializer.java:326)
at com.fasterxml.jackson.databind.deser.BuilderBasedDeserializer.deserialize(BuilderBasedDeserializer.java:143)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:226)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:203)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:23)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:375)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeSetAndReturn(MethodProperty.java:106)
at com.fasterxml.jackson.databind.deser.BuilderBasedDeserializer.deserializeFromObject(BuilderBasedDeserializer.java:
Same issue occurs with LocalDate
com.fasterxml.jackson.databind.JsonMappingException: Unexpected token (START_OBJECT), expected START_ARRAY: expected JSON Array, String or Number
at Source: org.mortbay.jetty.HttpParser$Input#d297c0; line: 1, column: 51
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164)
at com.fasterxml.jackson.databind.DeserializationContext.wrongTokenException(DeserializationContext.java:692)
at com.fasterxml.jackson.datatype.joda.deser.LocalDateDeserializer.deserialize(LocalDateDeserializer.java:50)
....
Why is the call chain passing a START_OBJECT in one case and START_ARRAY in the other?
To solve a similar problem I did the following,
I downloaded jackson-datatype-joda-2.2.1.jar from http://mvnrepository.com/artifact/com.fasterxml.jackson.datatype/jackson-datatype-joda/2.2.1 if you are using maven the dependency definition is there too.
then I added an annotation for every LocalDate field in my app as follows:
#JsonDeserialize(using=LocalDateDeserializer.class)
private LocalDate releasedDate;
the imports look like this:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.datatype.joda.deser.LocalDateDeserializer;
And the problem vanished.
Hope this helps!
I think this has to do with some discrepancy between serializer and deserializer; so that one produces the other (I think Joda module actually writes an array of ints, when registered).
This would most likely be because either deserializer or serializer registration is missing.
By default, without any extra handling, Jackson would consider Joda types just POJOs, and use getters/setters. But Joda module uses more compact representations (Strings, arrays).
So what may be happening is that serialization side is not using Joda module; and deserialization is.
you should be using both serialization and de-serialization for joda-time; against those fields which you are trying to save and fetch.
By doing so, we will give both side responsibilities to jackson (java to mongo/json and mongo/json to java conversions).
Sample code:
#JsonDeserialize(using= LocalDateDeserializer.class)
#JsonSerialize(using = LocalDateSerializer.class)
LocalDate dateFieldToBeConverted
and these are the imports:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
import com.fasterxml.jackson.databind.annotation.JsonSerialize
import com.fasterxml.jackson.datatype.joda.deser.LocalDateDeserializer
import com.fasterxml.jackson.datatype.joda.ser.LocalDateSerializer
import org.joda.time.LocalDate
After doing this, simple save and findOne queries on mongo (through java repo classes) will work without any issues. Hope this helps.
The key issue here is that Spring is converting JodaTime in a different way then for example Jersey.
This is what i had to do in my app-servlet.xml:
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="no.bouvet.jsonclient.spring.JsonClientJackson2ObjectMapperFactoryBean"/>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
Here you can find the no.bouvet.jsonclient.spring.JsonClientJackson2ObjectMapperFactoryBean from the java-json-client library
We're wanting to provide alternative PDF views as well as regular JSP views from our controllers and have added a ContentNegotiatingViewResolver and an XmlViewResolver to handle this.
All the examples I've found, including the Spring docs, return a simple view name, which the XmlViewResolver maps to a bean ID in its views.xml file ( in our case, a bean that writes PDF to the HttpResponse).
However we have our jsps organised in subfolders of the location defined in our InternalResourceViewResolver.
E.g.,
<bean id="viewResolver" class= "org.springframework.web.servlet.view.InternalResourceViewResolver" p:order="2">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
So, from within our controller we return view names like "a/b/c" for a JSP that is in /WEB-INF/pages/a/b/c.jsp.
This works fine for JSPs, except that you can't have a bean id defined in views.xml as 'a/b/c'; it's not a valid bean ID.
We've investigated several options that either don't work are not satisfactory:
Put all JSPs in a single folder so that we can just use a bean-id-naming-compatible view name that can be resolved by an XmlViewResolver. This works but isn't ideal for organising our JSPs.
Have multiple InternalResourceViewResolver definitions using different prefixes. This just doesn't work; the first resolver of this type does not return null if it fails to find a matching view, it just fails with an exception and subsequent ViewResolvers are not used.
Use a separate controller method (or conditional code in the controller that returns the view name depending on what is the requested content type or URL suffix); these solutions seem to defeat the purpose of keeping a Controller ignorant of its views.
Try using wild-cards in the location property of XmlViewResolver; this fails with an exception.
I'm sure there is a nice elegant solution but it is eluding me just now. Is there a better approach such that I can return a view name like 'a/b/c' which has the potential to be resolved by an XmlViewResolver ?
Thank you for any suggestions.
Richard
Of course, bean aliases are the way to go...after a bit of digging around:
In the views.xml file targetted by XmlViewResolver:
<bean id="PdfView" class="com.blah.PdfDocView" />
<alias name="PdfView" alias="/a/b/structuredDocument"/>
which maps '/a/b/structuredDocument' to the PdfDocView bean.
I was asked this question in an interview. I said no then he asked then how do I access other portlet controllers. I am new to spring and what I know is that in application context file we have beans that are nothing but controllers and their corresponding dependencies...which are defined like below:
<bean id="projectProfileSummaryController" class="com.ca.beacon.implproject.controllers.ProjectProfileSummaryController">
<property name="restTemplateBuilder" ref="restTemplateBuilder"/>
<property name="implementProjectService" ref="implementProjectService"/>
along with their views that is defined in view resolver.
Am I right or wrong?
First of all, one portlet can have multiple controller classes.
Second of all, according to docs for FrameworkPortlet (parent class of DispatcherPortlet):
Passes a "contextConfigLocation" portlet init-param to the context instance, parsing it into potentially multiple file paths which can be separated by any number of commas and spaces, like "test-portlet.xml, myPortlet.xml". If not explicitly specified, the context implementation is supposed to build a default location from the namespace of the portlet.
So yes, one portlet can have multiple context xml files.