<entity class="Map" name="Map" access="FIELD">
<table name="MAP"/>
<attributes>
<id name="id">
<column name="ID" nullable="false"/>
<generated-value strategy="SEQUENCE"/>
</id>
<basic name="updated">
<column name="UPDATED" nullable="true"/>
<temporal>DATETIME</temporal>
</basic>
<basic name="updated">
<column name="UPDATED" nullable="true"/>
<temporal>TIMESTAMP</temporal>
</basic>
</entity>
Wednesday, May 27, 2009
JPA: Mapping Created and Updated Columns
Friday, May 8, 2009
MySQL: Adding Created and Updated Columns
I had a requirement to add a Last-Modified header to GET requests for an entity called Map in a service I was developing. I figured it would be a good idea to track that information in the MySQL database backing the service instead of in the application itself with a column named UPDATED. In other words, I wouldn't have to explicitly set andupdate the values during the lifetime of the Map.
While I was at it, I also thought it would be a good idea to add a CREATEDcolumn to track when the Map came into existence in case that information would be useful later.
At table creation time you can add the columns with the following SQL (which omits any other useful attributes or columns):
CREATE TABLE MAP (The columns can also be added after the table has been created, assigning the defaults to each table row:
ID INT NOT NULL AUTO_INCREMENT,
CREATED DATETIME NOT NULL DEFAULT '1900-01-01 00:00:00',
UPDATED TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
);
ALTER TABLE MAP ADD CREATED DATETIME NOT NULL DEFAULT '1900-01-01 00:00:00';Finally a trigger can be used, which can be added at anytime, to have the CREATED column be given a value on an INSERT:
ALTER TABLE MAP ADD UPDATED TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
CREATE TRIGGER MAP_CREATED BEFORE INSERT ON MAPWith the trigger, the default on the CREATED column wouldn't exactly be needed, and in fact the table could be created without it, leaving the NOT NULL clause intact.
FOR EACH ROW SET NEW.CREATED = NOW();
The resulting table definition:
mysql> DESCRIBE MAP;
+---------+-----------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+-----------+------+-----+---------------------+----------------+
| ID | int(11) | NO | PRI | NULL | auto_increment |
| CREATED | datetime | NO | | 1900-01-01 00:00:00 | |
| UPDATED | timestamp | NO | | CURRENT_TIMESTAMP | |
+---------+-----------+------+-----+---------------------+----------------+
3 rows in set (0.00 sec)
Thursday, April 30, 2009
Mule: Sending a JMS Message to WebSphere MQ
MuleClient client = new MuleClient();I was having trouble sending a JMS message to endpoint hooked to the following WebSphere MQ connector. The connector has a JMS to Object transformer for the incoming message. Sending a String as in the example produced an execption related to the connection factory stating that the incoming object was of type Class and not a JMS message. The connector:
client.dispatch("jms://my.queue", "Message Payload" null);
<jms:connector name="jmsConnectorWMQ"The connection factory:
connectionFactory-ref="WMQConnectionFactory"
maxRedelivery="5"
specification="1.1"
persistentDelivery="true"
numberOfConcurrentTransactedReceivers="5">
<service-overrides inboundTransformer="Jms2Obj"/>
</jms:connector>
<jms:jmsmessage-to-object-transformer name="Jms2Obj"/>
<spring:bean name="WMQConnectionFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory">
<spring:property name="transportType" value="1"/>
<spring:property name="hostName" value="${jms.connection.hostname}"/>
<spring:property name="port" value="${jms.connection.port}"/>
<spring:property name="queueManager" value="${jms.queue.manager}"/>
<spring:property name="channel" value="${jms.connection.channel}"/>
</spring:bean>
I was able to create and send a JMS message with the following method. Without giving the ObjectToJMSMessage transformer an endpoint, an exception was thrown stating the transformer requires a javax.jms.Session. The String to send is transformed to a JMS message to make the connector happy.
The URL returned by the getUrl() method below was the address of a JMS queue, for example: jms://request.queue. Im using MuleClient.send() because I want the response returned synchronously.
The method:
protected String sendRequest(Object request) throws Exception {
EndpointFactory endpointFactory = new DefaultEndpointFactory();
MuleContext context = MuleServer.getMuleContext();
endpointFactory.setMuleContext(context);
ImmutableEndpoint endpoint = endpointFactory.getInboundEndpoint(getUrl());
ObjectToJMSMessage transformer = new ObjectToJMSMessage();
transformer.setEndpoint(endpoint);
Object transformedMessage = transformer.doTransform(request, "UTF-8");
MuleClient client = new MuleClient();
MuleMessage responseMessage = client.send(getUrl(), transformedMessage, null);
String response = responseMessage.getPayloadAsString(ENCODING);
return response;
}This seems like a lot of work to me to send a simple JMS message to WebSphere MQ, but it works. A suggestions for alternative would be greatly appreciated.A better approach: I left this as a comment but it doesn't display too nicely...
With com.ibm.mqjms.jar, sending the JMS message is much easier. I wish I would of found this earlier.With the following imports:
import com.ibm.jms.JMSTextMessage;The original method is greatly simplified to:
import com.ibm.mq.jms.MQJMSStringResources;
protected String sendRequest(Object request) throws Exception {
MQJMSStringResources resources = new MQJMSStringResources();
JMSTextMessage jmsMessage = new JMSTextMessage(resources, (String)request);
jmsMessage.setText((String)request);
MuleClient client = new MuleClient();
MuleMessage responseMessage = client.send(getUrl(), jmsMessage, null);
String response = responseMessage.getPayloadAsString(ENCODING);
return response;
}
Sunday, April 26, 2009
Using tidy to Format XML
tidy -utf8 -xml -w 255 -i -c -q -asxmlI like to use an alias to work with files easily:
$ alias xmltidy="tidy -utf8 -xml -w 255 -i -c -q -asxml"You can also change a file in place:
$ xmltidy some-file.xml > tidy-file.xml
$ xmltidy -m some-file.xml
Friday, April 3, 2009
Groovy: Pretty Printing XML
#!/usr/share/groovy/bin/groovySuggestions for alternatives would be appreciated!
import org.xml.sax.SAXParseException
def xml = new File(args[0]).text
def stringWriter = new StringWriter()
def printWriter = new PrintWriter(stringWriter)
try {
def node = new XmlParser().parseText(xml)
new XmlNodePrinter(printWriter).print(node)
println stringWriter.toString()
} catch(SAXParseException spe) {
println spe.getMessage()
}
Mule: Displaying HTTP Outbound Responses
I had been tasked with adding an endpoint to my Mule service for verifying other service endpoints. One of the requirements was that the endpoint be HTTP so that a browser could be used to retrieve the verification report.
Originally, when hitting the endpoint in my browser, the resulting HTML was displayed as plain text.
I resolved this by adding the HtmlResponseTransformer below:<http:endpoint name="VerificationEndpoint"It is worth noting the HTTP Transport Documentation states that HTTP endpoints are synchronous by default, but it did appear to be the case in my experience.
host="localhost"
port="28080"
path="services/verify"
method="GET"
synchronous="true"
responseTransformer-refs="HtmlResponseTransformer"/>
<message-properties-transformer name="HtmlResponseTransformer">
<add-message-property key="Content-Type" value="text/html"/>
</message-properties-transformer>
<model name="setup">
...
<service name="verify">
<inbound>
<http:inbound-endpoint ref="VerificationEndpoint"/>
</inbound>
<component>
<spring-object bean="endpointVerifier"/>
</component>
</service>
...
</model>
Wednesday, February 18, 2009
Maven Assemblies: Including Runtime Dependencies
Previously, I thought you had to list every runtime dependency you wanted to include in a dependencySet:
<dependencySets>But all runtime dependencies can be brought into the assembly with an empty dependencySet element (runtime scope implicitly includes compile scope):
<dependencySet>
<includes>
<include>commons-dbcp:commons-dbcp</include>
…
</includes>
<outputDirectory>mule/lib/user</outputDirectory>
</dependencySet>
</dependencySets>
<dependencySet/>This will put all the runtime dependencies in the root of the assembled artifact, so you can add an outputDirectory:
<dependencySet>And in the case where you want to exclude something (such as mule-#.tar.gz or isoft-#.tar.gz) you can add exclusions:
<outputDirectory>mule/lib/user</outputDirectory>
</dependencySet>
<dependencySet>Doing things this way puts a heavier burden on properly managing your dependencies however (which really is a good thing). If transitive dependencies you may not need are not excluded in the POM’s dependency declaration or the parent’s dependencyManagement, the transitive dependencies will end up in your artifact, leading to potential collisions and jar bloat. An example of an exclusion:
<outputDirectory>mule/lib/user</outputDirectory>
<excludes>
<exclude>*:tar.gz</exclude>
</excludes>
</dependencySet>
<dependency>You can run each of the following to help with your dependency manangement:
<groupId>toplink.essentials</groupId>
<artifactId>toplink-essentials</artifactId>
<scope>runtime</scope>
<excludes>
<exclude>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
</exclude>
</excludes>
</dependency>
mvn dependency:analyze
mvn dependency:resolve
mvn dependency:tree
