Proper ObjectFactory in MyBatis TypeHandler - spring

I'm creating a project in Spring-ws with MyBatis.
I have many web services definitions in xsd.
Spring is creating POJO classes based on xsd.
The problem is that in xsd I have fields that have parameter nillable="true"
like this:
<xs:element name="numericParam" type="xs:int" minOccurs="0" maxOccurs="1" nillable="true"/>
That field in generated POJO looks like this:
protected JAXBElement<Integer> numericParam;
I want to create custom TypeHandler in MyBatis config, to handle JAXBElement<Integer> types, but how can I know which ObjectFactory to use.
Is it possible to know which mapper is calling my custom TypeHandler? In TypeHandler all I have is column name.

This is not possible currently (version 3.4.6) in mybatis. No information about the context (like enclosing type or mapper method) is passed to handler.
If you do want to use jaxb generated types you would need to create a handler per field (of cause it make sense to have common base that would implement all the logic).

Related

Spring ResourceBundleMessageSource multiple properties files configuration in spring xml file?

For example I am having two properties file like message and query. how can configure in the spring xml
Well, you could use the below code snippet.
<context:property-placeholder
location="classpath:dao.properties,
classpath:services.properties,
classpath:user.properties"
ignore-unresolvable="true"/>
In this, the order attribute needs to be specified to fix the order in which these are processed by Spring.
All property placeholders minus the last one (highest order) should have ignore-unresolvable="true" to allow the resolution mechanism to pass to others in the context without throwing an exception

Custom annotation like #Value

I need to create a means to add a custom annotation like
#Value("${my.property}")
However, in my case I need to get the value from a database rather then a properties file.
Basically I would like to create a bean on container startup that reads in property name value pairs from a database and can then inject these into fields belonging to other beans.
Approach #1:
One way is to create an Aspect, with a point-cut expression that matches any method having this annotation.
Your aspect will then:
Read the property value in the annotation
Look up the required value an inject it into the class.
AOP Kickstart
Here's a guide to getting started with AOP in Spring
http://www.tutorialspoint.com/spring/aop_with_spring.htm
Joinpoint matching
Here's a reference that describes how to create a join-point that matches on annotations: http://eclipse.org/aspectj/doc/next/adk15notebook/annotations-pointcuts-and-advice.html
Approach #2:
Another way is to use a BeanFactoryPostProcessor - this is essentially how a PropertyPlaceholderConfigurer works.
It will look at your bean definitions, and fetch the underlying class.
It will then check for the annotation in the class, using reflection.
It will update the bean definition to include injecting the property as per the value in the annotation.
. . actually I think approach #2 sounds more like what you want - all of the processing happens on "start-up". . . (In actual fact your modifying the bean recipes even before startup). . whereas if you used AOP, you'd be intercepting method invocations, which might be too late for you?
Namespace Handler
If you wanted you could even create your own Spring namespace handler to turn on your post processor in a terse way. Eg:
<myApp:injectFromDb />
as an alternative to:
<bean class="MyDatabaseLookupProcessorImpl etc, etc. />
Update: Approach #3
As of Spring 3.1 there's also the PropertySourcesPlaceholderConfigurer, that will provide most of the plumbing for you, so you can achieve this with less code.
Alternatively you should be able to configure kind of properties repository bean and then use it in SpEL directly in #Value annotation.
Let's say you'd have bean called propertiesRepository in your context that implements following interface:
interface PropertiesRepository {
String getProperty(String propertyName);
}
then on bean where you want to inject values you can use following expression
#Value("#{propertiesRepository.getProperty('my.property')}")
String myProperty;
You can use #Value annotation by injecting database configuration in application environment itself.
I know this is an old question but I didn't find an exact solution. So documenting it here.
I have already answered the same on different forum.
Please refer to this answer for exact solution to your problem.

Couldn't generate data contract code

Here's a sample of the code I'm trying to generate:
<xs:simpleType name="IVL">
<xs:restriction base="xs:duration"/>
</xs:simpleType>
<xs:complexType name="SF">
<xs:attribute name="varde" type="xs:boolean"/>
</xs:complexType>
The Complex type is generated but the simple types are left out.
Am I missing a setting or something or aren't WSCF.Blue able to handle simple types?
I am not aware of any commonnly used XSD-to-code binding approach that on .NET would generate classes for simple types, except when XSD simpleTypes are restricted using enumeration facets.
This article pretty much stands for WSCF as well at least in the area of Type/primitive mapping.
Just for trivia, JAXB - a Java based approach for binding XML to Java classes - has this option built in (i.e. to generate classes even for simple types).

Spring config and runtime separation

When using Spring it is rather cumbersome to incorporate runtime data in bean construction. While there are techniques to circumvent this separation, I have a feeling that it was put in place for a reason. My question is whether this is a known paradigm, and if there is any litterature discussing it. Personally I find that it has both advantages and drawbacks, depending on the dynamicity of the app.
You have at least five well known methods to pass runtime data to beans configuration:
Use ApplicationContextInitializer to add PropertySources to the Enviroment.
Use SPEL to inject dependencies.
Use FactoryBeans.
Use the factory-bean and factory-method attributes.
If you write the class that need the runtime data, you only need to inject the
collaborator that provide it.
For example
<bean id="requestAttributeReader" class="example.RequestAttributeReader" />
<bean id="requestInjectedBean" class="example.RequestInjectedBean" scope="request">
<property name="a" value="#{requestAttributeReader.a}" />
</bean>
Class RequestAttributeReader {
public String getA() {
return RequestContextHolder.getAttributes().getAttribute("a");
}
}
EDIT
The bean description files of an IoC container lets you to configure implementors on application beans. This is normally a static definition of the implementation classes that you want to use for a concrete configuration, so xml it's good for it.
If you need to choose an implementor based on runtime then you need to write code to choose them and then inform the container.
for example, using PropertySources and PropertyPlaceholderConfigurer:
String service = "example.NormalService";
if (BOSS_USERNAME.equals(System.getProperty("user.name")))
service = "example.BossService";
ctx.getEnvironment().getPropertySources().addFirst(new PropertiesPropertySource("service", service));
<bean id="service" class="${service}" />
The same could be done with a ServiceFactoryBean, a external ServiceFactory, SPEL and so on...
Maybe, you are interested on replacing implementations at runtime, ie changing the Service implementation in all beans that depends on when the container is already refreshed. (without destroy and refresh).
As far as I know, the framework don't provides a clear way to do it.
Sounds like you should look at spring binding, eg:
public String create(#Valid Market market, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest) {
So this will take request params that match the fields in the Market object and set them in that object. It will also validated the params/object since there is the #Valid annotation.
This binding can be customised with PropertyEditors or Converters.
If the market object is annotated #Configurable, it can use #Autowired and #Value annotations to configure the bean when spring creates it.

JAX-WS RI does not enforce XSD restrictions

I am currently developing a few Web services using the JAX-WS reference implementation (version 2.1.7). They are contract-based, that is, the WSDL and XSD files are not generated by wsgen.
This allows me to freely use XSD restrictions to strengthen validation of values passed to my services through SOAP messages. Here are two examples of such "restricted" XSD elements:
<xsd:element name="maxResults" minOccurs="1">
<xsd:simpleType>
<xsd:restriction base="xsd:positiveInteger">
<xsd:minInclusive value="1"/>
<xsd:maxInclusive value="1000"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="lastName" minOccurs="0">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:minLength value="1"/>
<xsd:maxLength value="25"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
I added the #SchemaValidation annotation to my service classes to enforce schema validation. However, JAX-WS does not enforce validation rules as expected. The behaviour is as follows:
Missing mandatory elements are correctly reported (e.g., missing maxResults).
Invalid values (e.g., character data in an integer field) are correctly reported too.
Interval restriction violations (e.g., maxResults > 1000 or maxResults < 1) pass through the validation process without being reported and are injected into my JAXB-generated Java structures. Even negative values are considered valid despite the xsd:positiveInteger type!
String length constraint violations (e.g., lastName length over 25 characters) are not reported either.
In other words, restrictions that appear in <xsd:element> tags are correctly enforced but <xsd:restriction> elements seem to be totally ignored by JAXB when used in a JAX-WS-based context.
I wrote a test class to check my XSD restrictions using bare JAXB (no JAX-WS). As a result, all restrictions are correctly enforced.
This gives me the feeling that there might be a bug in the usage of JAXB by JAX-WS... unless there is something I am doing incorrectly, of course...
Am I missing something fundamental here?!?
Thanks in advance for any help,
Jeff
I finally found what's wrong...
In order to get my Web services to work in a JUnit context, i.e. published through Endpoint.publish(), I had to remove the wsdlLocation attribute from my #WebService annotations. If I don't, the wsdlLocation = "WEB-INF/wsdl/SearchIndividualsV1_0.wsdl" passed to the #WebService annotation clashes with the URL value passed to the Endpoint.publish() method, http://127.0.0.1:9000/rpe-ws/SearchIndividuals.
After reading Glen Mazza's Weblog (http://www.jroller.com/gmazza/entry/soap_xml_schema_validation), Additional Notes section, I put back the wsdlLocation attribute and all restrictions are now properly enforced.
In other words, removing the wsdlLocation in a #WebService annotation does not prevent the service itself from working, but prevents restrictions declared in <xsd:restrictions> elements from being properly enforced. Restrictions declared in <xsd:element> elements, however, are still correctly enforced.
I am therefore getting back to having to solve that wsdlLocation compatibility problem to make my unit tests work properly, but this is way less critical than non-working validations in a production context...
Just in case... Anyone has an idea about this WSDL location incompatibility when running a Web service in a non-Web context?
Thanks,
Jeff
Oh brother!...
In order to override the wsdlLocation for my JUnit tests, I created derivations of my Web service implementations that override only the #WebService annotation. As a result, I ran into the same problem I finally solved this morning (ref. my first answer above).
After doing plenty of tests, I figured out that it's the presence of a #WebService-annotated class extending my Web service implementation that prevents XSD validation from properly handling <xsd:restriction> tags.
To illustrate this bizarre behaviour, let's suppose I have the following classes:
#WebService(...)
public interface JeffWebService {...}
#WebService(..., wsdlLocation = "path/myWsdl.wsdl", ...)
public class JeffWebServiceImpl implements JeffWebService {...}
where path/myWsdl.wsdl correctly locates the WSDL. Then XSD validation works properly, i.e. the content of my first answer above is totally valid.
I now add the following class that I use in my JUnit-based Endpoint.publish() calls:
#WebService(..., wsdlLocation = "alternatePath/myWsdl.wsdl", ...)
public class TestWebServiceImpl extends JeffWebServiceImpl {}
that overrides nothing but the #WebService annotation. Then XSD validation excludes <xsd:restriction> tags as it used to do before specifying the wsdlLocation attribute at all, despite the fact that I still use the JeffWebServiceImpl implementation in my non-JUnit code! If I comment out the annotation in TestWebServiceImpl, then everything works properly again, except for unit tests, of course.
In other words, as soon as there is some class extending my Web service implementation in the classpath, the #WebService annotation of the most specific class overrides all others, regardless of the actual class I use in a regular Web application context. Weird, isn't it?!?
Bottom line: I will disable Endpoint-based unit tests for now. If I (or anyone reading this thread) find a clean, non-bogus way to integrate both production and JUnit configurations, I will consider putting them back in my JUnit test suite.
I hope this thread will help anyone running into the same problem solve it faster than I did...
Jeff

Resources