Synchronous Message send and receive using JMS template and Spring Boot - spring
I am after sending/receiving call to JMS queue synchronously using JMS Template and Spring boot. I went through official spring doc for JMS template but of no help.
I am not too sure about calling receive() method specifically or it will automatically receive message once send() is invoked. Since this is synchronous call I only need to receive message that I've sent (with the correlation Id).
Any help in this regard would be appreciated. Please let me know if you need any further info.
Update!!
Below is my spring boot code.
JMSSConfig.java
#Configuration
#EnableJms
public class JMSConfig {
#Bean
public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory, DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
// This provides all boot's default to this factory, including the message converter
configurer.configure(factory, connectionFactory);
// You could still override some of Boot's default if necessary.
return factory;
}
#Bean
public MarshallingMessageConverter createMarshallingMessageConverter(final Jaxb2Marshaller jaxb2Marshaller) {
System.out.println("executing createMarshallingMessageConverter");
return new MarshallingMessageConverter(jaxb2Marshaller);
}
#Bean
public Jaxb2Marshaller createJaxb2Marshaller(#Value("${context.path}") final String contextPath, #Value("${schema.location}") final String schemaLocaation) {
System.out.println("executing Jaxb2Marshaller");
Resource schemaResource = new ClassPathResource(schemaLocaation);
Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
jaxb2Marshaller.setContextPath(contextPath);
jaxb2Marshaller.setSchema(schemaResource);
Map<String, Object> properties = new HashMap<>();
properties.put(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxb2Marshaller.setMarshallerProperties(properties);
return jaxb2Marshaller;
}
}
Sender and receiver code
#Component
public class Receiver {
#Autowired
JmsTemplate jmsTemplate;
#JmsListener(destination = "mailbox", containerFactory="myFactory")
public void receiveMessage(CacheMsgType submitEventType) {
System.out.println("Received <" + submitEventType + ">");
}
public void send(CacheMsgType submitEventType) {
jmsTemplate.convertAndSend("mailbox", submitEventType);
System.out.println("Successfully sent a message.");
}
}
JAXB Generated classes
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "SubmitEventType", namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", propOrder = {
"eventType",
"clientApplication",
"clientReferenceID",
"systemDate",
"transactionAcceptTime",
"bsb",
"accountNumber",
"productcode",
"accttypecode",
"trancode",
"meid",
"baiCode",
"baiDecs",
"tranamount",
"amountonhold",
"recordedlimit",
"currentbalance",
"availablebalance",
"description",
"reference",
"payer"
})
public class SubmitEventType {
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String eventType;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String clientApplication;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String clientReferenceID;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String systemDate;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String transactionAcceptTime;
#XmlElement(name = "BSB", namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String bsb;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String accountNumber;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String productcode;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String accttypecode;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String trancode;
#XmlElement(name = "MEID", namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String meid;
#XmlElement(name = "BAICode", namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String baiCode;
#XmlElement(name = "BAIDecs", namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String baiDecs;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String tranamount;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String amountonhold;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String recordedlimit;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String currentbalance;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String availablebalance;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String description;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String reference;
#XmlElement(namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected String payer;
/**
* Gets the value of the eventType property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getEventType() {
return eventType;
}
/**
* Sets the value of the eventType property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setEventType(String value) {
this.eventType = value;
}
/**
* Gets the value of the clientApplication property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getClientApplication() {
return clientApplication;
}
/**
* Sets the value of the clientApplication property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setClientApplication(String value) {
this.clientApplication = value;
}
/**
* Gets the value of the clientReferenceID property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getClientReferenceID() {
return clientReferenceID;
}
/**
* Sets the value of the clientReferenceID property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setClientReferenceID(String value) {
this.clientReferenceID = value;
}
/**
* Gets the value of the systemDate property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getSystemDate() {
return systemDate;
}
/**
* Sets the value of the systemDate property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setSystemDate(String value) {
this.systemDate = value;
}
/**
* Gets the value of the transactionAcceptTime property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getTransactionAcceptTime() {
return transactionAcceptTime;
}
/**
* Sets the value of the transactionAcceptTime property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setTransactionAcceptTime(String value) {
this.transactionAcceptTime = value;
}
/**
* Gets the value of the bsb property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getBSB() {
return bsb;
}
/**
* Sets the value of the bsb property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setBSB(String value) {
this.bsb = value;
}
/**
* Gets the value of the accountNumber property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getAccountNumber() {
return accountNumber;
}
/**
* Sets the value of the accountNumber property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setAccountNumber(String value) {
this.accountNumber = value;
}
/**
* Gets the value of the productcode property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getProductcode() {
return productcode;
}
/**
* Sets the value of the productcode property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setProductcode(String value) {
this.productcode = value;
}
/**
* Gets the value of the accttypecode property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getAccttypecode() {
return accttypecode;
}
/**
* Sets the value of the accttypecode property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setAccttypecode(String value) {
this.accttypecode = value;
}
/**
* Gets the value of the trancode property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getTrancode() {
return trancode;
}
/**
* Sets the value of the trancode property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setTrancode(String value) {
this.trancode = value;
}
/**
* Gets the value of the meid property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getMEID() {
return meid;
}
/**
* Sets the value of the meid property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setMEID(String value) {
this.meid = value;
}
/**
* Gets the value of the baiCode property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getBAICode() {
return baiCode;
}
/**
* Sets the value of the baiCode property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setBAICode(String value) {
this.baiCode = value;
}
/**
* Gets the value of the baiDecs property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getBAIDecs() {
return baiDecs;
}
/**
* Sets the value of the baiDecs property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setBAIDecs(String value) {
this.baiDecs = value;
}
/**
* Gets the value of the tranamount property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getTranamount() {
return tranamount;
}
/**
* Sets the value of the tranamount property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setTranamount(String value) {
this.tranamount = value;
}
/**
* Gets the value of the amountonhold property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getAmountonhold() {
return amountonhold;
}
/**
* Sets the value of the amountonhold property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setAmountonhold(String value) {
this.amountonhold = value;
}
/**
* Gets the value of the recordedlimit property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getRecordedlimit() {
return recordedlimit;
}
/**
* Sets the value of the recordedlimit property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setRecordedlimit(String value) {
this.recordedlimit = value;
}
/**
* Gets the value of the currentbalance property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getCurrentbalance() {
return currentbalance;
}
/**
* Sets the value of the currentbalance property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setCurrentbalance(String value) {
this.currentbalance = value;
}
/**
* Gets the value of the availablebalance property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getAvailablebalance() {
return availablebalance;
}
/**
* Sets the value of the availablebalance property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setAvailablebalance(String value) {
this.availablebalance = value;
}
/**
* Gets the value of the description property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getDescription() {
return description;
}
/**
* Sets the value of the description property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setDescription(String value) {
this.description = value;
}
public String getReference() {
return reference;
}
public void setReference(String value) {
this.reference = value;
}
public String getPayer() {
return payer;
}
public void setPayer(String value) {
this.payer = value;
}
}
CashMsgType.java
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
#XmlRootElement(name = "CacheMsg", namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent")
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "CacheMsgType", namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", propOrder = {
"submitEvent"
})
public class CacheMsgType {
#XmlElement(name = "SubmitEvent", namespace = "nabgroup.com/nab/schema/PaymentsExecution/SubmitPaymentEvent", required = true)
protected List<SubmitEventType> submitEvent;
public List<SubmitEventType> getSubmitEvent() {
if (submitEvent == null) {
submitEvent = new ArrayList<SubmitEventType>();
}
return this.submitEvent;
}
}
It seems sending on to mailbox queue is working but receiving gives error
Exception
2018-05-05 10:44:53.280 WARN 4120 --- [enerContainer-1] o.s.j.l.DefaultMessageListenerContainer : Execution of JMS message listener failed, and no ErrorHandler has been set.
org.springframework.jms.listener.adapter.ListenerExecutionFailedException: Listener method could not be invoked with incoming message
Endpoint handler details:
Method [public void com.nab.services.mq.Receiver.receiveMessage(com.nab.services.dto.CacheMsgType)]
Bean [com.nab.services.mq.Receiver#134bfc8]
; nested exception is org.springframework.messaging.converter.MessageConversionException: Cannot convert from [javax.xml.bind.JAXBElement] to [com.nab.services.dto.CacheMsgType] for org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter$LazyResolutionMessage#3621aa, failedMessage=org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter$LazyResolutionMessage#3621aa
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:118) ~[spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:77) ~[spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:736) ~[spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:696) ~[spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:674) ~[spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:318) [spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:257) [spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1189) [spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1179) [spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1076) [spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_162]
Caused by: org.springframework.messaging.converter.MessageConversionException: Cannot convert from [javax.xml.bind.JAXBElement] to [com.nab.services.dto.CacheMsgType] for org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter$LazyResolutionMessage#3621aa
at org.springframework.messaging.handler.annotation.support.PayloadArgumentResolver.resolveArgument(PayloadArgumentResolver.java:144) ~[spring-messaging-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:116) ~[spring-messaging-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:137) ~[spring-messaging-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:109) ~[spring-messaging-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:114) ~[spring-jms-5.0.5.RELEASE.jar:5.0.5.RELEASE]
... 10 common frames omitted
This might be implementation specific, but once the message is sent, you should be able to read the message id from the message itself.
Related
How to avoid casting to a JAXBElement while making a SOAP webservice call?
I am having a spring boot java application. I am calling a soap web service using spring webservice template . the webservice call always return a JAXBElement. the following is my code snippet. JAXBElement<ItemResponse> itemResponse = (JAXBElement<ItemResponse> ) getWebServiceTemplate().marshalSendAndReceive( this.cconfServiceConfiguration.getServices().getLocation(), itemRequest, new SoapActionCallback(this.cconfServiceConfiguration.getServices().getGetItemAction())); return itemResponse.getValue(); The marshalSendAndReceive returns a JAXBElement. Is there any way i can rewrite the code so that it will return an Object of ItemResponse so that i can avoid casting. The following is the ItemResponse class declaration. #XmlAccessorType(XmlAccessType.FIELD) #XmlType(name = "ItemResponse", propOrder = { "result", "item" }) public class ItemResponse { #XmlElement(required = true) protected Result result; protected Item item; /** * Gets the value of the result property. * * #return * possible object is * {#link Result } * */ public Result getResult() { return result; } /** * Sets the value of the result property. * * #param value * allowed object is * {#link Result } * */ public void setResult(Result value) { this.result = value; } /** * Gets the value of the item property. * * #return * possible object is * {#link Item } * */ public Item getItem() { return item; } /** * Sets the value of the item property. * * #param value * allowed object is * {#link Item } * */ public void setItem(Item value) { this.item = value; } } really appreciate if you can throw some information
Rabbit MQ org.springframework.amqp.AmqpIOException: java.net.UnknownHostException
I am facing unknown-host exception for below code. I am not sure what is wrong with code. #Component #Configuration public class RabbitListenerContainerFactory { static final Logger logger = LoggerFactory.getLogger(RabbitListenerContainerFactory.class); #Autowired RabbitMqConfig rabbitMqConfig; #Autowired EPPQ2Subscriber receiver; #Autowired EPPQ2ChanelAwareSubscriber receiverChanel; public RabbitListenerContainerFactory(ConfigurableApplicationContext ctx) { printContainerStartMsg(); } private void printContainerStartMsg() { logger.info("----------- Scrubber Container Starts --------------"); } #Bean public SimpleMessageListenerContainer queueListenerContainer(ConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) { SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory); container.setQueueNames(rabbitMqConfig.getSubscriberQueueName()); // container.setQueueNames("SampleQueue"); /*This just for testing.. !*/ container.setMessageListener(listenerAdapter); container.setAcknowledgeMode(AcknowledgeMode.MANUAL); container.setDeclarationRetries(5);// This is default to 3, We can twick this and move this to prop container.setPrefetchCount(100); //Tell the broker how many messages to send to each consumer in a single request. return container; } #Bean MessageListenerAdapter listenerAdapter(EPPQ2Subscriber receiver) { return new MessageListenerAdapter(receiver, "receiveMessage"); } /*#Bean MessageListenerAdapter listenerAdapterWithChanel(EPPQ2ChanelAwareSubscriber receiverChanel) { return new MessageListenerAdapter(receiverChanel); }*/ #Bean ConnectionFactory connectionFactory () { final CachingConnectionFactory connectionFactory = new CachingConnectionFactory(); connectionFactory.setAddresses(Arrays.toString(rabbitMqConfig.getSubscriberHosts())); //connectionFactory.setHost(Arrays.toString(rabbitMqConfig.getSubscriberHosts())); connectionFactory.setVirtualHost("hydra.services"); connectionFactory.setPort(rabbitMqConfig.getSubscriberPort()); connectionFactory.setUsername(rabbitMqConfig.getSubscriberUsername()); connectionFactory.setPassword(rabbitMqConfig.getSubscriberPassword()); return connectionFactory; } } I am able to see rabbit running on the host I can see admin console here http://hostname:15672/ Tel net is working Telnet hostname 15672 timeout 3 bash -c 'cat < /dev/null > /dev/tcp/hostname/15672 '; echo $? Here is log : org.springframework.amqp.AmqpIOException: java.net.UnknownHostException:host-name Edit 1 public class RabbitMqConfig { private String [] subscriberHosts; private int subscriberPort; private String [] publisherHosts; private int publisherPort; private String subscriberUsername; private String subscriberPassword; private String publisherUsername; private String publisherPassword; private String subscriberQueueName; private String publisherQueueName; private String publisherTopic; private String routingKey; /** * * #return -read queue hosts */ public String[] getSubscriberHosts() { return subscriberHosts; } /** * * #return -read queue port */ public int getSubscriberPort() { return subscriberPort; } /** * * #return -write queue hosts */ public String[] getPublisherHosts() { return publisherHosts; } /** * * #return -write queue port */ public int getPublisherPort() { return publisherPort; } /** * * #return -Read Queue user name */ public String getSubscriberUsername() { return subscriberUsername; } /** * * #return Read Queue password */ public String getSubscriberPassword() { return subscriberPassword; } /** * * #return -Write Queue user name */ public String getPublisherUsername() { return publisherUsername; } /** * * #return -Write Queue password */ public String getPublisherPassword() { return publisherPassword; } /** * * #return -Write Queue name */ public String getSubscriberQueueName() { return subscriberQueueName; } /** * * #return --Read Queue name */ public String getPublisherQueueName() { return publisherQueueName; } /** * * #return */ public String getPublisherTopic() { return publisherTopic; } /** * * #return */ public String getRoutingKey() { return routingKey; } #PostConstruct public void getAIMCredentails() { tempApiCallMock(); } private void tempApiCallMock() { String [] host = {"10.30.190.25"}; this.subscriberHosts = host; this.subscriberPort = 5672; this.subscriberQueueName = "hydra.Syphon.q1"; this.subscriberUsername = "dftp_subscriber"; this.subscriberPassword = "dftp_subscriber"; this.publisherHosts = host; this.publisherPort = 5672; this.publisherUsername = "dftp_publisher"; this.publisherPassword = "dftp_publisher"; } Thanks for Correcting me I changed the port to 5672 But still the same issue. and my telnet host 5672 works
The connectionFactory.setAddresses(Arrays.toString(rabbitMqConfig.getSubscriberHosts())); is wrong. The setAddresses() expects a comma-separate string, not a string representation of the array. See its JavaDocs: /** * Set addresses for clustering. * This property overrides the host+port properties if not empty. * #param addresses list of addresses with form "host[:port],..." */ public void setAddresses(String addresses) {
gson.toJson() throws StackOverflowError and I dont have a circular dependency
I am trying to generate a JSON Gson gson = new Gson(); String json = gson.toJson(item); But every time i try to I keep getting a stackoverflow error: java.lang.StackOverflowError: null at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:239) at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:968) at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:112) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:239) at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:112) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:239) at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:968) at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:112) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:239) It is caused when i try to convert DataTableResults class which contains a list of Transactions.class as its property field to a string. The DataTableResult class looks like this : public class DataTableResults<T> { /** The draw. */ private String draw; /** The records filtered. */ private String recordsFiltered; /** The records total. */ private String recordsTotal; /** The list of data objects. */ #SerializedName("data") List<T> listOfDataObjects; /** * Gets the draw. * * #return the draw */ public String getDraw() { return draw; } /** * Sets the draw. * * #param draw the draw to set */ public void setDraw(String draw) { this.draw = draw; } /** * Gets the records filtered. * * #return the recordsFiltered */ public String getRecordsFiltered() { return recordsFiltered; } /** * Sets the records filtered. * * #param recordsFiltered the recordsFiltered to set */ public void setRecordsFiltered(String recordsFiltered) { this.recordsFiltered = recordsFiltered; } /** * Gets the records total. * * #return the recordsTotal */ public String getRecordsTotal() { return recordsTotal; } /** * Sets the records total. * * #param recordsTotal the recordsTotal to set */ public void setRecordsTotal(String recordsTotal) { this.recordsTotal = recordsTotal; } /** * Gets the list of data objects. * * #return the listOfDataObjects */ public List<T> getListOfDataObjects() { return listOfDataObjects; } /** * Sets the list of data objects. * * #param listOfDataObjects the listOfDataObjects to set */ public void setListOfDataObjects(List<T> listOfDataObjects) { this.listOfDataObjects = listOfDataObjects; } } while the Transactions.class looks like this #Entity #Table(name = "TRANS") public class Transactions extends DefaultEntity { public enum TRANSACTIONTYPE{WITHDRAW, DEPOSIT, WIN, LOSS} #ManyToOne(targetEntity = User.class) #JoinColumn(name="player") private User player; private double amount; #Enumerated(EnumType.STRING) private TRANSACTIONTYPE transactiontype; private String referenceID; private String detail; private String token; public TRANSACTIONTYPE getTransactiontype() { return transactiontype; } public Transactions setTransactiontype(TRANSACTIONTYPE transactiontype) { this.transactiontype = transactiontype; return this; } public double getAmount() { return amount; } public Transactions setAmount(double amount) { this.amount = amount; return this; } public String getReferenceID() { return referenceID; } public Transactions setReferenceID(String referenceID) { this.referenceID = referenceID; return this; } public String getDetail() { return detail; } public Transactions setDetail(String detail) { this.detail = detail; return this; } public String getToken() { return token; } public Transactions setToken(String token) { this.token = token; return this; } public User getPlayer() { return player; } public Transactions setPlayer(User player) { this.player = player; return this; } } according to this post, it is supposed to be caused by a circular dependency, but in my case it is not cause i dont have one. What else could cause such error ?
You should remove extends DefaultEntity, you don't need it and may bring circular dependency. Also you have a #ManyToOne relationship with User, that may cause circular dependency if User also have a reference to Transactions. If you have it in both parts, you should exclude it from serialization with transient on one part at least.
#ManyToMany spring-mvc, spring-data-jpa, update error - failed to lazily initialize a collection of role
Very well-known exception "failed to lazily initialize a collection of role". I read many blogs, many suggestions but they did not work for my case. Can anybody help me to understand how to resolve my issue ? All these work in WAR spring-webmvc (JSP view). I have entities Person and Address. 1 Person can have many Addresses, at 1 Address can live many persons (family). Look : package abc.def.data.model; import java.io.Serializable; import java.util.Collections; import java.util.HashSet; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.Table; import org.hibernate.annotations.Type; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; /** */ #Entity #Table( name = "PERSON" ) public class Person implements Serializable { private static final long serialVersionUID = 1L; /* * ID of person. */ #Id #GeneratedValue( strategy = GenerationType.AUTO ) private long id; /* * email and used as login of person. */ #Column( name = "email", length = 128, nullable = false, unique = true ) private String email; /* * Fullname of person. */ #Column( name = "fullname", length = 128, nullable = true ) private String fullName; /* * Person`s password. It is stored as encrypted value. Nobody know this value except person. There used * Spring encryption mechanism. Look at the */ #Column( name = "password", length = 128, nullable = false ) private String password; /* * */ #Column( name = "role", length = 16, nullable = false ) private String role; #Column( name = "timezone", nullable = false ) private int timezone; #Column( name = "created", nullable = false ) #Type( type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime" ) private DateTime created; #Column( name = "updated", nullable = false ) #Type( type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime" ) private DateTime updated; #Column( name = "isenabled", nullable = false ) #Type( type = "true_false" ) private boolean enabled; /* * Addresses of person. One person can has many addresses. In that time many persons can live in one * address (family). */ #ManyToMany( fetch = FetchType.LAZY, cascade = {CascadeType.ALL} ) #JoinTable( name = "PERSON_ADDRESS", joinColumns = {#JoinColumn( name = "personid", referencedColumnName = "id" )}, inverseJoinColumns = {#JoinColumn( name = "addressid", referencedColumnName = "id" )} ) private Set<Address> addresses = new HashSet<Address>(0); /** * closed Contructor. Need for JPA. */ protected Person() { } /** * Public Contructor. * * #param fullName * #param email * #param role * #param timezone * #param created * #param udated */ public Person( String fullName, String email, String password, String role, int timezone, DateTime created, DateTime udated, boolean enabled ) { this.fullName = fullName; this.email = email; this.password = password; this.role = role; this.timezone = timezone; this.created = created; updated = udated; this.enabled = enabled; } /** * Public Contructor without enabled status field. By default user is DISABLED here. * * #param fullName * #param email * #param role * #param timezone * #param created * #param udated */ public Person( String fullName, String email, String password, String role, int timezone, DateTime created, DateTime udated ) { this.fullName = fullName; this.email = email; this.password = password; this.role = role; this.timezone = timezone; this.created = created; updated = udated; this.enabled = false; } /* * (non-Javadoc) * #see java.lang.Object#toString() */ #Override public String toString() { return String.format( "Person [id=%s, fullName=%s, email=%s, password=%s, role=%s, timezone=%s, created=%s," + " updated=%s, enabled=%s, {address}]", id, fullName, email, password, role, timezone, created, updated, enabled ); } /** * Getter. * * #return the id */ public long getId() { return id; } /** * Getter. * * #return the fullName */ public String getFullName() { return fullName; } /** * Getter. * * #return the email */ public String getEmail() { return email; } /** * Getter. * * #return the password */ public String getPassword() { return password; } /** * Getter. * * #return the role */ public String getRole() { return role; } /** * Getter. * * #return the timezone */ public int getTimezone() { return timezone; } /** * Getter. * * #return the created */ public DateTime getCreated() { return new DateTime( created, DateTimeZone.forOffsetMillis( this.timezone ) ); } /** * Getter. * * #return the updated */ public DateTime getUpdated() { return new DateTime( updated, DateTimeZone.forOffsetMillis( this.timezone ) ); } /** * Getter. * * #return the enabled */ public boolean isEnabled() { return enabled; } /** * Getter. * * #return the addressCollection */ public Set<Address> getAddresses() { //force clients through our add and remove methods return Collections.unmodifiableSet( addresses ); } public void addAddress( Address address ) { //avoid circular calls : assumes equals and hashcode implemented if ( !addresses.contains( address ) ) { addresses.add( address ); //add method to Product : sets 'other side' of association address.addPerson( this ); } } public void removeAddress( Address address ) { //avoid circular calls : assumes equals and hashcode implemented if ( !addresses.contains( address ) ) { addresses.remove( address ); //add method to Product : sets 'other side' of association address.removePerson( this ); } } /** * Setter. * * #param id * the id to set */ public void setId( long id ) { this.id = id; } /** * Setter. * * #param fullName * the fullName to set */ public void setFullName( String fullName ) { this.fullName = fullName; } /** * Setter. * * #param email * the email to set */ public void setEmail( String email ) { this.email = email; } /** * Setter. * * #param password * the password to set */ public void setPassword( String password ) { this.password = password; } /** * Setter. * * #param role * the role to set */ public void setRole( String role ) { this.role = role; } /** * Setter. * * #param timezone * the timezone to set */ public void setTimezone( int timezone ) { this.timezone = timezone; } /** * Setter. * * #param created * the created to set */ public void setCreated( DateTime created ) { this.created = created; } /** * Setter. * * #param updated * the updated to set */ public void setUpdated( DateTime updated ) { this.updated = updated; } /** * Setter. * * #param enabled * the enabled to set */ public void setEnabled( boolean enabled ) { this.enabled = enabled; } /** * Setter. * * #param addressCollection * the addressCollection to set */ public void setAddresses( Set<Address> addressCollection ) { this.addresses = addressCollection; } /* * (non-Javadoc) * #see java.lang.Object#hashCode() */ #Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (int) ( id ^ ( id >>> 32 ) ); return result; } /* * (non-Javadoc) * #see java.lang.Object#equals(java.lang.Object) */ #Override public boolean equals( Object obj ) { if ( this == obj ) return true; if ( obj == null ) return false; if ( getClass() != obj.getClass() ) return false; Person other = (Person) obj; if ( id != other.id ) return false; return true; } } Address : package abc.def.data.model; import java.io.Serializable; import java.util.Collections; import java.util.HashSet; import java.util.Set; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.ManyToMany; import javax.persistence.Table; import javax.persistence.UniqueConstraint; /** * Addresses of person. <br /> * One person can has many addresses. In that time many persons can live in one address (family). * */ #Entity #Table( name = "ADDRESS", uniqueConstraints = {#UniqueConstraint( columnNames = {"country", "city", "street", "housenum"} )}, indexes = {} ) public class Address implements Serializable { private static final long serialVersionUID = 1L; /* * Address ID. */ #Id #GeneratedValue( strategy = GenerationType.AUTO ) private long id; /* * Name of country. */ #Column( length = 128 ) private String country; /* * Name of city. */ #Column( length = 64 ) private String city; /* * Name of street. */ #Column( length = 64 ) private String street; /* * Number of house. */ #Column( name = "housenum" ) private Integer houseNumber; /* * Users who live at this Address. */ #ManyToMany( fetch = FetchType.LAZY, mappedBy = "addresses" ) public Set<Person> persons = new HashSet<Person>( 0 ); /** * Getter. * * #return the id */ public long getId() { return id; } /** * Getter. * * #return the country */ public String getCountry() { return country; } /** * Getter. * * #return the city */ public String getCity() { return city; } /** * Getter. * * #return the street */ public String getStreet() { return street; } /** * Getter. * * #return the houseNumber */ public Integer getHouseNumber() { return houseNumber; } /** * Getter. * * #return the personCollection */ public Set<Person> getPersons() { return Collections.unmodifiableSet( persons ); } /** * Setter. * * #param id * the id to set */ public void setId( long id ) { this.id = id; } /** * Setter. * * #param country * the country to set */ public void setCountry( String country ) { this.country = country; } /** * Setter. * * #param city * the city to set */ public void setCity( String city ) { this.city = city; } /** * Setter. * * #param street * the street to set */ public void setStreet( String street ) { this.street = street; } /** * Setter. * * #param houseNumber * the houseNumber to set */ public void setHouseNumber( Integer houseNumber ) { this.houseNumber = houseNumber; } /** * Setter. * * #param personCollection * the personCollection to set */ public void setPersons( Set<Person> personCollection ) { this.persons = personCollection; } /* * (non-Javadoc) * #see java.lang.Object#toString() */ #Override public String toString() { return String.format( "Address [id=%s, country=%s, city=%s, street=%s, houseNumber=%s, {person}]", id, country, city, street, houseNumber ); } /** * */ public void addPerson( Person person ) { //assumes equals and hashcode implemented: avoid circular calls if ( !persons.contains( person ) ) { persons.add( person ); //add method to Product : sets 'other side' of association person.addAddress( this ); } } /** * */ public void removePerson( Person person ) { //assumes equals and hashcode implemented: avoid circular calls if ( !persons.contains( person ) ) { persons.remove( person ); } //add method to Product : sets 'other side' of association person.removeAddress( this ); } /* * (non-Javadoc) * #see java.lang.Object#hashCode() */ #Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (int) ( id ^ ( id >>> 32 ) ); return result; } /* * (non-Javadoc) * #see java.lang.Object#equals(java.lang.Object) */ #Override public boolean equals( Object obj ) { if ( this == obj ) return true; if ( obj == null ) return false; if ( getClass() != obj.getClass() ) return false; Address other = (Address) obj; if ( id != other.id ) return false; return true; } } In case New registration and new person and new address - no problem. It passed find. In PersonService #Service I have : // create new Person Person newPerson = new Person( fullName, email, password, role, timezone, created, udated, true ); // add addresses - it is possible have more 1 address in registration newPerson.setAddresses( (Set<Address>) addrList ); try { newPerson = personRepository.save( newPerson ); } catch (Exception e) { actionResult.setError( true ); actionResult.addErrorItem( "error", e.getMessage() ); } LOG.debug( "Created new person : {}", newPerson.toString() ); actionResult.setObject( newPerson ); return actionResult; /* * Check given addresses for existing. */ private Collection<Address> checkAddresses( Set<Address> addrList, Person newPerson ) { Set<Address> newAddresses = new HashSet<Address>(); Address addr = null; for (Address address : addrList) { addr = addressRepository.findByCountryAndCityAndStreetAndHouseNumber( address.getCountry(), address.getCity(), address.getStreet(), address.getHouseNumber() ); if ( addr != null ) { addr.getPersons().size(); } addr = addr == null ? address : addr; newAddresses.add( addr ); LOG.debug( "checked address {}", addr.toString() ); } return newAddresses; } personRepository : public interface PersonRepository extends JpaRepository<Person, Long> { } In case new user enter existing address - it checks (found) in DB. When it found it have to be added to newPerson() . In this case exception arise. I tried use address.getPerson().size - also exception . Also I do not want use EAGER. is It possible ?
If you don't have an active transaction or open thread-bound EntityManager, Spring Data JPA will create a new EntityManager for each call on a repository. Then it closes the EntityManager before returning, leading to the exception you're getting when Hibernate tries to lazy-load. There are two ways to deal with this. One is to use transactions, possibly by applying #Transactional as appropriate. The other is to use OpenEntityManagerInViewFilter, which will create a thread-bound EntityManager at the beginning of each request and hold it open for the entire request. In this case I think a transaction is called for because you're doing an INSERT that depends on previous SELECTs. OpenEntityManagerInViewFilter is very handy for using lazy-loaded collections in views, but it doesn't provide any transaction management.
Jedis and JOhm Error
I am using Redis installed on Windows via chocolatey and setup jedis and JOhm in java project. The Redis server is live Redis version 2.6 When I want to save a Java object like the one in the post I got an error message. java.lang.NoSuchMethodError: redis.clients.jedis.Jedis.sadd(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Long; at redis.clients.johm.Nest.sadd(Nest.java:168) at redis.clients.johm.JOhm.save(JOhm.java:220) at redis.clients.johm.JOhm.save(JOhm.java:146) This is my java object: /** * */ package com.smsgh.unitysmpp.MessageProcessor; import java.io.Serializable; import org.joda.time.DateTime; import redis.clients.johm.Attribute; import redis.clients.johm.Id; import redis.clients.johm.Model; /** * #author Arsene Tochemey GANDOTE This class holds the Messages that needs a * Delivery Receipt */ #Model public class StoredShortMessage implements Serializable { /** * */ private static final long serialVersionUID = 6185862961624213864L; #Id private Integer id; // session Id #Attribute private Long smppSessionId; // Message Id #Attribute private String messageId; // ESME Account Number# #Attribute private Long accountNumber; // ESME Account Id #Attribute private String accountId; // ESME API Pub Key #Attribute private String apiPublicKey; // Message state #Attribute private String messageState; // Network Error #Attribute private String networkErrorCode; // First 20 Characters of the message #Attribute private String mesgFirstLines; // esme TCP/IP connection #Attribute private String ip; // message submitted datetime #Attribute private DateTime submitDate; // final state date #Attribute private DateTime doneDate; // source address #Attribute private byte srcTon; #Attribute private byte srcNpi; #Attribute private String srcAddr; // destination address #Attribute private byte destTon; #Attribute private byte destNpi; #Attribute private String destAddr; // delivery state #Attribute private char dlrState; /** * */ public StoredShortMessage() { } /** * #return the smppSessionId */ public Long getSmppSessionId() { return smppSessionId; } /** * #param smppSessionId * the smppSessionId to set */ public void setSmppSessionId(Long smppSessionId) { this.smppSessionId = smppSessionId; } /** * #return the messageId */ public String getMessageId() { return messageId; } /** * #param messageId * the messageId to set */ public void setMessageId(String messageId) { this.messageId = messageId; } /** * #return the accountNumber */ public Long getAccountNumber() { return accountNumber; } /** * #param accountNumber * the accountNumber to set */ public void setAccountNumber(Long accountNumber) { this.accountNumber = accountNumber; } /** * #return the accountId */ public String getAccountId() { return accountId; } /** * #param accountId * the accountId to set */ public void setAccountId(String accountId) { this.accountId = accountId; } /** * #return the apiPublicKey */ public String getApiPublicKey() { return apiPublicKey; } /** * #param apiPublicKey * the apiPublicKey to set */ public void setApiPublicKey(String apiPublicKey) { this.apiPublicKey = apiPublicKey; } /** * #return the messageState */ public String getMessageState() { return messageState; } /** * #param messageState * the messageState to set */ public void setMessageState(String messageState) { this.messageState = messageState; } /** * #return the networkErrorCode */ public String getNetworkErrorCode() { return networkErrorCode; } /** * #param networkErrorCode * the networkErrorCode to set */ public void setNetworkErrorCode(String networkErrorCode) { this.networkErrorCode = networkErrorCode; } /** * #return the mesgFirstLines */ public String getMesgFirstLines() { return mesgFirstLines; } /** * #param mesgFirstLines * the mesgFirstLines to set */ public void setMesgFirstLines(String mesgFirstLines) { this.mesgFirstLines = mesgFirstLines; } /** * #return the ip */ public String getIp() { return ip; } /** * #param ip * the ip to set */ public void setIp(String ip) { this.ip = ip; } /** * #return the submitDate */ public DateTime getSubmitDate() { return submitDate; } /** * #param submitDate * the submitDate to set */ public void setSubmitDate(DateTime submitDate) { this.submitDate = submitDate; } /** * #return the doneDate */ public DateTime getDoneDate() { return doneDate; } /** * #param doneDate * the doneDate to set */ public void setDoneDate(DateTime doneDate) { this.doneDate = doneDate; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } /** * #return the srcTon */ public byte getSrcTon() { return srcTon; } /** * #param srcTon * the srcTon to set */ public void setSrcTon(byte srcTon) { this.srcTon = srcTon; } /** * #return the srcNpi */ public byte getSrcNpi() { return srcNpi; } /** * #param srcNpi * the srcNpi to set */ public void setSrcNpi(byte srcNpi) { this.srcNpi = srcNpi; } /** * #return the srcAddr */ public String getSrcAddr() { return srcAddr; } /** * #param srcAddr * the srcAddr to set */ public void setSrcAddr(String srcAddr) { this.srcAddr = srcAddr; } /** * #return the destTon */ public byte getDestTon() { return destTon; } /** * #param destTon * the destTon to set */ public void setDestTon(byte destTon) { this.destTon = destTon; } /** * #return the destNpi */ public byte getDestNpi() { return destNpi; } /** * #param destNpi * the destNpi to set */ public void setDestNpi(byte destNpi) { this.destNpi = destNpi; } /** * #return the destAddr */ public String getDestAddr() { return destAddr; } /** * #param destAddr * the destAddr to set */ public void setDestAddr(String destAddr) { this.destAddr = destAddr; } /** * #return the dlrState */ public char getDlrState() { return dlrState; } /** * #param dlrState * the dlrState to set */ public void setDlrState(char dlrState) { this.dlrState = dlrState; } } Can someone tell me what can be the error? Thanks
To solve I have to download the source code and use it. I think there is a bug in the jar file I downloaded.
Download Project Source from https://github.com/xetorthio/johm Edit pom.xml change Jedis version from 1.5.1 to 2.4.2 or latest <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.4.2</version> <type>jar</type> <scope>compile</scope> </dependency> Compile project and build jar , use this new jar in your project