HibernateConfigException An exception occurred parsing configuration - nhibernate

I created the console application using Nhibernate.
I created hibernate.cfg.xml file
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"
assembly="NHibernateDemo"
namespace="NHibernateDemo">
<session-factory>
<property name="connection.connection_string_name">default</property>
<property name="connection.driver_class">Nhibernate.Driver.SqlClientDriver</property>
<property name="dialect">Nhibernate.Dialect.MsSql2008Dialect</property>
<mapping assembly ="NHibernateDemo" />
</session-factory>
</hibernate-configuration>
and it's my code
using System;
using System.Linq;
using System.Reflection;
using HibernatingRhinos.Profiler.Appender.NHibernate;
using NHibernate.Cfg;
using NHibernate.Dialect;
using NHibernate.Driver;
using NHibernate.Linq;
namespace NHibernateDemo
{
internal class Program
{
static void Main(string[] args)
{
NHibernateProfiler.Initialize();
var cfg = new Configuration();
cfg.Configure("hibernate.cfg.xml");
var sessionFactory = cfg.BuildSessionFactory();
int newId;
using (var session = sessionFactory.OpenSession())
using (var tx = session.BeginTransaction())
{
var newCustomer = CreateCustomer();
Console.WriteLine("Before saving:");
Console.WriteLine(newCustomer);
session.Save(newCustomer);
newId = newCustomer.Id;
tx.Commit();
}
using (var session = sessionFactory.OpenSession())
using (var tx = session.BeginTransaction())
{
var newCustomer = session.Load<Customer>(newId);
Console.WriteLine("\nAfter saving:");
Console.WriteLine(newCustomer);
session.Save(newCustomer);
tx.Commit();
}
Console.WriteLine("Enter any key to exit...");
Console.ReadKey();
}
private static Customer CreateCustomer()
{
return new Customer
{
FirstName = "Jonh",
LastName = "Doe",
Points = 100,
HasGoldStatus = true,
// MemberSince = new DateTime(2012, 1, 1),
CreditRating = CustomerCreditRating.Neutral,
AverageRating = 42.44454647,
Adress = new Location()
{
Street = "123 Somewhere Avenue",
City = "Nowhere",
Province = "Alberta",
Country = "Canada"
}
};
}
}
}
but when I tried to debug my application, I got HibernateConfigException The 'assembly' attribute is not declared
How to fix that?
UPD if I remove attributes assembly and namespace from hibernate.cfg.xml file I get other error
MappingException was unhandled
UPD2 My mapping file (Build Action = Embedded Resource)
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="NHibernateDemo"
namespace="NHibernateDemo">
<class name="Customer">
<id name="Id">
<generator class="native" />
</id>
<property name="FirstName"/>
<property name="LastName"/>
<property name="AverageRating"/>
<property name="Points"/>
<property name="HasGoldStatus"/>
<property name="MemberSince" type="UtcDateTime"/>
<property name="CreditRating" type="CustomerCreditRatingType"/>
<component name="Adress">
<property name="Street"/>
<property name="City"/>
<property name="Province"/>
<property name="Country"/>
</component>
</class>
</hibernate-mapping>

You need to add the assambly in code:
var cfg = new Configuration();
cfg.AddAssembly("NHibernateDemo");
cfg.Configure("hibernate.cfg.xml");

Related

Can I use NHibernate.Cfg.Configuration in Fluent-NHibernate when building a session factory?

I want to use the NHibernate configuration for FluentNhibernate when building a session.
This how I am constructing my factory session:
lock (_factorylock)
{
if (_factory == null)
{
nHibernateConfig = delegate
{
GetConfiguration();
};
nHibernateConfig.Invoke(GetConfiguration());
var cfg = Fluently.Configure().
Database(MsSqlConfiguration.MsSql2012)
.ExposeConfiguration( nHibernateConfig)
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<UserMap>());
_factory = cfg.BuildSessionFactory();
}
}
I am not sure about the delegate that I am using as well as the invoke method that I am calling there.
The method GetConfiguration looks like this:
private static NHibernate.Cfg.Configuration GetConfiguration()
{
var configuration = new NHibernate.Cfg.Configuration();
var baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
var configFile = Directory.GetFiles(baseDirectory, ConfigFile, SearchOption.AllDirectories).FirstOrDefault();
return configuration.Configure(configFile);
}
and of course, I have the xml config that contains a connection string:
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="dialect">NHibernate.Dialect.MsSql2012Dialect, NHibernate</property>
<property name="connection.connection_string">Database=authentication; Port=3306; Server=127.0.0.1; Uid=root; Pwd=; persistsecurityinfo=True;SslMode=none </property>
<property name="adonet.batch_size">100</property>
</session-factory>
</hibernate-configuration>
Figured it out.
There is no need for the delege and the GetConfiguration method.
All that I had to do was to insatiate the configuration object
var configuration = new Configuration();
configuration.Configure();
var cfg = Fluently.Configure(configuration)
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<UserMap>());
_factory = cfg.BuildSessionFactory();
worked like a charm and my code is a lot cleaner.

Apache TomEE external ActiveMQ resource not rolling back in distributed transaction

I am trying to achieve a distributed transaction in Apache TomEE. In words, the flow is:
A message reader (i.e. a message driven bean) reads from a queue (1) and processes one message triggering:
one or more inserts/updates on a database (2)
sending a message to another queue (3)
Operations 1, 2, & 3 are all part of the same XA transaction controlled by TomEE. Therefore, under any circumstances they either all fail or all succeed.
tomee.xml
<?xml version="1.0" encoding="UTF-8"?>
<tomee>
this resource adapter is just necessary to tell tomee to not start internal ActiveMq instance
<Resource id="MyAdapter" type="ActiveMQResourceAdapter">
BrokerXmlConfig
ServerUrl tcp://fakehost:666
</Resource>
<Resource id="jms/MyIncomingConnFactory" type="javax.jms.ConnectionFactory" class-name="org.apache.activemq.ActiveMQXAConnectionFactory">
BrokerURL tcp://externalhost:61616?jms.redeliveryPolicy.maximumRedeliveries=0
</Resource>
<Resource id="jms/MyOutgoingConnFactory" type="javax.jms.ConnectionFactory" class-name="org.apache.activemq.ActiveMQXAConnectionFactory">
BrokerURL tcp://externalhost:61616?jms.redeliveryPolicy.maximumRedeliveries=0
</Resource>
<Resource id="jms/MyOutgoingQueue" class-name="org.apache.activemq.command.ActiveMQQueue">
PhysicalName MY_OUTGOING_QUEUE
</Resource>
<Resource id="jms/MyIncomingQueue" class-name="org.apache.activemq.command.ActiveMQQueue">
PhysicalName MY_INCOMING_QUEUE
</Resource>
<Resource id="jdbc/myDBXAPooled" type="DataSource">
XaDataSource myDBXA
DataSourceCreator dbcp
JtaManaged true
UserName TestUser
Password TestPassword
MaxWait 2000
ValidationQuery SELECT 1
MaxActive 15
</Resource>
<Resource id="myDBXA" type="XADataSource" class-name="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource">
Url jdbc:mysql://localhost:3306/test
User TestUser
Password TestPassword
</Resource>
</tomee>
Springconfig.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.2.xsd">
<!-- <jee:jndi-lookup jndi-name="myDBXAPooled" id="myDatasource" resource-ref="true" /> -->
<jee:jndi-lookup jndi-name="jms/MyOutgoingConnFactory" id="myOutgoingConnFactory" resource-ref="true" />
<jee:jndi-lookup jndi-name="jms/MyIncomingConnFactory" id="myIncomingConnFactory" resource-ref="true" />
<jee:jndi-lookup jndi-name="jms/MyOutgoingQueue" id="myOutgoingQueue" resource-ref="true" />
<jee:jndi-lookup jndi-name="jms/MyIncomingQueue" id="myIncomingQueue" resource-ref="true" />
<jee:jndi-lookup jndi-name="jdbc/myDBXAPooled" id="myDatasource" resource-ref="true" />
<tx:jta-transaction-manager/>
<!-- <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/> -->
<!-- the previous two ways of getting the transactionManager seems equivalent and both get Geronimo -->
</beans>
SpringConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.2.xsd">
<bean id="messageListener" class="com.test.MyListener">
<property name="connectionFactory" ref="myIncomingConnFactory" />
<property name="destination" ref="myIncomingQueue" />
<!-- <property name="sessionTransacted" value="true" /> -->
<property name="concurrentConsumers" value="1" />
<property name="maxConcurrentConsumers" value="6" />
<property name="messageListener" ref="myMessageProcessor" />
<property name="transactionManager" ref="transactionManager" />
<property name="taskExecutor" ref="msgListenersTaskExecutor" />
</bean>
<bean id="myMessageProcessor" class="com.test.MyMessageReceiver">
<property name="forwardConnectionFactory" ref="myOutgoingConnFactory" />
<property name="forwardQueue" ref="myOutgoingQueue" />
<property name="datasource" ref="myDatasource" />
</bean>
<bean id="msgListenersTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"/>
</beans>
MyMessageReceiver.java:
package com.test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.sql.DataSource;
import org.apache.log4j.Logger;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
public class MyMessageReceiver implements MessageListener {
static Logger log = Logger.getLogger(MyMessageReceiver.class);
private ConnectionFactory forwardConnectionFactory;
private Queue forwardQueue;
private DataSource datasource;
public void setForwardConnectionFactory(ConnectionFactory connFactory) {
forwardConnectionFactory=connFactory;
}
public void setforwardQueue(Queue queue) {
forwardQueue=queue;
}
public void setDatasource(DataSource ds) {
datasource=ds;
}
#Override
#Transactional(propagation=Propagation.REQUIRED)
public void onMessage(Message message) {
log.info("************************************");
MyListener listener = (MyListener)SpringContext.getBean("messageListener");
listener.printInfo();
log.info("************************************");
TextMessage msg = (TextMessage) message;
String text = null;
try {
text = msg.getText();
if (text != null) log.info("MESSAGE RECEIVED: "+ text);
updateDB(text); // function call to update DB
sendMsg(text); // function call to publish messages to queue
System.out.println("****************Rollback");
// Throwing exception to rollback DB, Message should not be
// published and consumed message sent to a DLQ
//(Broker side DLQ configuration already done)
throw new RuntimeException();
//if (text!=null && text.indexOf("rollback")!=-1) throw new RuntimeException("Message content includes the word rollback");
} catch (Exception e) {
log.error("Rolling back the entire XA transaction");
log.error(e.getMessage());
throw new RuntimeException("Rolled back because of "+e.getMessage());
}
}
private void updateDB(String text) throws Exception {
Connection conn = null;
PreparedStatement ps = null;
try {
System.out.println("*******datasource "+datasource);
conn = datasource.getConnection();
System.out.println("*******conn "+conn.getMetaData().getUserName());
if (conn!=null) {
System.out.println("*******conn "+conn.getMetaData().getUserName());
ps = conn.prepareStatement("INSERT INTO MY_TABLE (name) VALUES(?)");
ps.setString(1, text);
ps.executeUpdate();
}
} catch (Exception e) {
throw e;
} finally {
if (ps!=null) {
try {
ps.close();
} catch (SQLException e) {
log.error(e.getMessage());
// do nothing
}
}
if (conn!=null) {
try {
conn.close();
} catch (SQLException e) {
log.error(e.getMessage());
// do nothing
}
}
}
}
private void sendMsg(String msgToBeSent) throws Exception {
javax.jms.Connection conn = null;
Session session = null;
try {
System.out.println("*************forwardConnectionFactory"+forwardConnectionFactory);
conn = forwardConnectionFactory.createConnection();
session = conn.createSession(true, Session.AUTO_ACKNOWLEDGE);
MessageProducer messageProducer = session.createProducer(forwardQueue);
TextMessage msg = session.createTextMessage(msgToBeSent);
messageProducer.send(msg);
} catch (Exception e) {
throw e;
} finally {
if (session != null) {
try {
session.close();
} catch (JMSException e) {
// do nothing
}
}
if (conn != null) {
try {
conn.close();
} catch (JMSException e) {
// do nothing
}
}
}
}
}
MyListener.java:
package com.test;
import javax.transaction.Status;
import javax.transaction.SystemException;
import org.apache.log4j.Logger;
import org.springframework.jms.listener.DefaultMessageListenerContainer;
import org.springframework.transaction.jta.JtaTransactionManager;
public class MyListener extends DefaultMessageListenerContainer {
static Logger log = Logger.getLogger(MyListener.class);
public void printInfo() {
try {
log.info("trans manager="+((JtaTransactionManager)this.getTransactionManager()).getTransactionManager()+","+((JtaTransactionManager)this.getTransactionManager()).getTransactionManager().getStatus()+", this.isSessionTransacted()="+this.isSessionTransacted());
log.info("STATUS_ACTIVE="+Status.STATUS_ACTIVE);
log.info("STATUS_COMMITTEDE="+Status.STATUS_COMMITTED);
log.info("STATUS_COMMITTING="+Status.STATUS_COMMITTING);
log.info("STATUS_MARKED_ROLLBACK="+Status.STATUS_MARKED_ROLLBACK);
log.info("STATUS_NO_TRANSACTION="+Status.STATUS_NO_TRANSACTION);
log.info("STATUS_PREPARED="+Status.STATUS_PREPARED);
log.info("STATUS_PREPARING="+Status.STATUS_PREPARING);
log.info("STATUS_ROLLEDBACK="+Status.STATUS_ROLLEDBACK);
log.info("STATUS_ROLLING_BACK="+Status.STATUS_ROLLING_BACK);
log.info("STATUS_UNKNOWN="+Status.STATUS_UNKNOWN);
} catch (SystemException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void forceRollback() {
try {
((JtaTransactionManager)this.getTransactionManager()).getTransactionManager().setRollbackOnly();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SystemException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
After updating the database and sending the message to the outgoing queue I am purposefully throwing a RuntimeException just to test the transaction rollback of both the database and the message broker.
All three operations are committed in case of success, but it only rolls back the database operation in case of failure, while the two JMS operations are committed anyway.
It could either be:
wrong settings in my tomee.xml (especially queue connection factories) or somewhere else
a bug??
I already spent quite much time fighting with the thing and searching for possible solutions.
It would be great to hear your opinion on this and, once again, advanced apologies if it turns out to be a mistake on my side.
I believe you need to use the ActiveMQ JCA resource adapter to ensure that connections are automatically enlisted into the XA transaction. Try this:
<tomee>
<Resource id="MyJmsResourceAdapter" type="ActiveMQResourceAdapter">
# Do not start the embedded ActiveMQ broker
BrokerXmlConfig =
ServerUrl = tcp://externalhost:61616?jms.redeliveryPolicy.maximumRedeliveries=0
</Resource>
<Resource id="jms/MyIncomingConnFactory" type="javax.jms.ConnectionFactory">
resourceAdapter = MyJmsResourceAdapter
transactionSupport = xa
</Resource>
<Resource id="jms/MyOutgoingConnFactory" type="javax.jms.ConnectionFactory">
resourceAdapter = MyJmsResourceAdapter
transactionSupport = xa
</Resource>
<Resource id="jms/MyOutgoingQueue" type="javax.jms.Queue"/>
<Resource id="jms/MyIncomingQueue" type="javax.jms.Queue"/>
<Resource id="jdbc/myDBXAPooled" type="DataSource">
XaDataSource myDBXA
DataSourceCreator dbcp
JtaManaged true
UserName TestUser
Password TestPassword
MaxWait 2000
ValidationQuery SELECT 1
MaxActive 15
</Resource>
<Resource id="myDBXA" type="XADataSource" class-name="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource">
Url jdbc:mysql://localhost:3306/test
User TestUser
Password TestPassword
</Resource>
</tomee>

Insert not being reflected in later Select

I’m developing a web app with JSF and Hibernate, and I’m facing a problem with Hibernate. At some point, I want to INSERT a row in a table. Just after that, I want to retrieve the 3 last inserted elements of the same table. The problem is that the INSERT is being made correctly (I checked that with a DB Client), but when I try to retrieve those 3 elements, the one I have just inserted is not returned by the SELECT statement. It seems like a kind of hibernate session problem, not reflecting the change when I make the SELECT. I attach the relevant part of the code:
hibernate.cfg.xml:
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/habana</property>
<property name="hibernate.connection.username">root</property>
<property name="connection.password"></property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="current_session_context_class">thread</property>
<property name="show_sql">true</property>
<property name="hibernate.cache.use_second_level_cache">false</property>
<property name="hibernate.cache.use_query_cache">false</property>
<mapping class="org.blk.lahabana.model.ClaseMovimiento"/>
<mapping class="org.blk.lahabana.model.Devolucion"/>
<mapping class="org.blk.lahabana.model.DevolucionProducto"/>
<mapping class="org.blk.lahabana.model.DevolucionProductoId"/>
<mapping class="org.blk.lahabana.model.Evento"/>
<mapping class="org.blk.lahabana.model.Movimiento"/>
<mapping class="org.blk.lahabana.model.Pedido"/>
<mapping class="org.blk.lahabana.model.PedidoProducto"/>
<mapping class="org.blk.lahabana.model.PedidoProductoId"/>
<mapping class="org.blk.lahabana.model.Permiso"/>
<mapping class="org.blk.lahabana.model.Producto"/>
<mapping class="org.blk.lahabana.model.TipoProducto"/>
<mapping class="org.blk.lahabana.model.Trabajador"/>
<mapping class="org.blk.lahabana.model.Turno"/>
<mapping class="org.blk.lahabana.model.TurnoTrabajador"/>
<mapping class="org.blk.lahabana.model.TurnoTrabajadorId"/>
<mapping class="org.blk.lahabana.model.Usuario"/>
</session-factory>
</hibernate-configuration>
HibernateUtil:
public class HibernateUtil {
/** Logger for this class and subclasses */
protected static final Log logger = LogFactory.getLog(HibernateUtil.class);
private static SessionFactory sessionFactory;
static {
try {
sessionFactory = new AnnotationConfiguration().configure()
.buildSessionFactory();
} catch (Throwable ex) {
logger.error("Error al crear el sessionFactory de Hibernate",ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
// Alternatively, we could look up in JNDI here
return sessionFactory;
}
public static void closeSession() {
// Close caches and connection pools
getSessionFactory().close();
}
}
EventsController:
public String create(){
String view = "";
Integer id = eventosService.createEvent(evento);
if(id !=null){
FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Evento Guardado", "El evento se ha guardado con éxito");
FacesContext.getCurrentInstance().addMessage(null, facesMsg);
}
else{
FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Evento No Guardado", "Se ha producido un error al guardar el evento");
FacesContext.getCurrentInstance().addMessage(null, facesMsg);
}
view = dashboardController.input();
return view;
}
#Override
public Integer createEvent(Evento event) {
Integer result = null;
event.setEstado(Constants.EVENT_STATE_PLANED);
boolean saved = eventoDao.save(event);
if( saved ){
result = event.getId();
}
return result;
}
public boolean save(T entity) {
Session hbsession = HibernateUtil.getSessionFactory().getCurrentSession();
Transaction transaction = null;
boolean result = false;
try {
transaction = hbsession.beginTransaction();
hbsession.save(entity);
hbsession.flush();
transaction.commit();
result = true;
} catch (HibernateException e) {
logger.error("Error al guardar una entidad entidad",e);
if(transaction != null){
transaction.rollback();
}
}
finally{
if(hbsession != null && hbsession.isOpen()){
hbsession.close();
}
}
return result;
}
DashboardController:
public String input(){
String view = "dashboard";
// Obtenemos los útimos eventos
List<Evento> events = eventosService.getLastEvents();
// Convertimos los eventos al VO para la vista
this.lastEvents = new ArrayList<EventoResumenVO>();
for (Evento evento : events) {
this.lastEvents.add(eventoResumenConverter.convertFromEvent(evento));
}
return view;
}
#Override
public List<Evento> getLastEvents() {
return eventoDao.findLastEvents(3);
}
#SuppressWarnings("unchecked")
#Override
public List<Evento> findLastEvents(Integer number) {
Session hbsession = HibernateUtil.getSessionFactory().getCurrentSession();
Transaction transaction = null;
List<Evento> result = null;
try {
transaction = hbsession.beginTransaction();
Criteria criteria = hbsession.createCriteria(entityClass);
criteria.setFetchMode("movimientos", FetchMode.JOIN);
criteria.addOrder(Order.desc("fechaFin"));
criteria.setMaxResults(number.intValue());
result = criteria.list();
} catch (HibernateException e) {
logger.error("Error al recuperar la lista de entidades",e);
if(transaction != null){
transaction.rollback();
}
}
finally{
if(hbsession != null && hbsession.isOpen()){
hbsession.close();
}
}
return result;
}
Thanks for helping!

publisher failed to recieve first message on rabbitmq

im trying to implement an integration test on RabbitMQ, so i have a setup of a published and basic consumer, to send and receive messages across a queue.
try
{
ConnectionFactory factory = new ConnectionFactory();
factory.setUsername("guest");
factory.setPassword("guest");
factory.setHost("localhost");
factory.setPort(5672);
connection = factory.newConnection();
channel = connection.createChannel();
channel.queueDeclare(RPC_QUEUE_NAME_KEY, DURABLE, EXCLUSIVE, AUTO_DELETE, null);
channel.exchangeDeclare(RPC_EXCHANGE_NAME, "direct");
String queueName = channel.queueDeclare().getQueue();
channel.queueBind(queueName, RPC_EXCHANGE_NAME, RPC_QUEUE_NAME_KEY);
channel.basicQos(1);
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume(queueName, false, consumer);
System.out.println(" [x] Awaiting RPC requests");
while(true)
{
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
BasicProperties props = delivery.getProperties();
BasicProperties replyProps = new BasicProperties.Builder().correlationId(props.getCorrelationId()).build();
try
{
RetrieveUnencryptedCardsResponse response = null;
JAXBContext jaxbContext = JAXBContext.newInstance(RetrieveUnencryptedCardsRequest.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
StringReader reader = new StringReader(new String(delivery.getBody()));
JAXBElement<RetrieveUnencryptedCardsRequest> message = jaxbUnmarshaller.unmarshal(new StreamSource(reader), RetrieveUnencryptedCardsRequest.class);
response = retrieveUnencryptedCardsResponse(message);
JAXBContext jaxbMarshallingContext = JAXBContext.newInstance(RetrieveUnencryptedCardsResponse.class);
Marshaller jaxbMarshaller = jaxbMarshallingContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
ByteArrayOutputStream xmlStream = new ByteArrayOutputStream();
jaxbMarshaller.marshal(new JAXBElement<RetrieveUnencryptedCardsResponse>(_RetrieveUnencryptedCardsResponse_QNAME, RetrieveUnencryptedCardsResponse.class, null,
response), xmlStream);
data = xmlStream.toByteArray();
xmlStream.close();
}
catch(Exception e)
{
logger.error(e);
}
finally
{
channel.basicPublish("", props.getReplyTo(), replyProps, data);
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
if(connection != null)
{
try
{
connection.close();
}
catch(Exception ignore)
{
}
}
}
}
The problem occurs when I try to receive the messages from the queue. i cant receive the first message, but i can from the second one.
i don't know if this might help:
<rabbit:queue id="account.amqp.default.reply.queue"
name="${vendor.account.amqp.default.reply.queue}" durable="${connector.fixed.queue.durable}"
auto-delete="false" exclusive="false">
<rabbit:queue-arguments>
<entry key="x-message-ttl">
<value type="java.lang.Long">${vendor.account.amqp.default.reply.ttl}</value>
</entry>
<entry key="x-ha-policy" value="${vendor.account.default.queue.ha.policy}" />
<entry key="x-ha-policy-params"
value="#{ T(org.springframework.util.CollectionUtils).arrayToList((T(org.springframework.util.StringUtils).commaDelimitedListToSet('${vendor.account.default.queue.ha.nodes}')).toArray())}" />
</rabbit:queue-arguments>
</rabbit:queue>
<rabbit:template id="pamRabbitTemplate"
connection-factory="connectionFactory" message-converter="accountMarshallingMessageConverter"
reply-timeout="${gateway.reply.timeout}" reply-queue="${vendor.account.amqp.default.reply.queue}">
<rabbit:reply-listener
concurrency="${vendor.account.amqp.default.reply.queue.consumers}" />
</rabbit:template>
<bean id="accountMarshallingMessageConverter"
class="org.springframework.amqp.support.converter.MarshallingMessageConverter">
<property name="marshaller" ref="fuelNotificationWsMarshaller" />
<property name="unmarshaller" ref="fuelNotificationWsMarshaller" />
</bean>
and in pamRabbitTemplate:
<int:channel id="channel.accounts.request" />
<int:channel id="channel.accounts.reply" />
<int:channel id="channel.accounts.outbound.request" />
<int:channel id="channel.accounts.outbound.reply" />
<int:channel id="channel.accounts.error" />
<int-amqp:outbound-gateway request-channel="channel.accounts.outbound.request"
reply-channel="channel.accounts.outbound.reply" amqp-template="pamRabbitTemplate"
exchange-name="${pam.exchange.service.account}" routing-key="${pam.routingkey.service.account}"
requires-reply="false" />
<int:gateway id="gateway.account"
service-interface="notification.fuelnotification.infrastructure.integration.RetrieveAccountsGateway"
error-channel="channel.error" default-reply-timeout="${gateway.reply.timeout}">
<int:method name="retrieveUnencryptedCards"
request-channel="channel.accounts.request" reply-channel="channel.accounts.reply" />
</int:gateway>
<int:transformer id="accountsReqTf" method="transform"
input-channel="channel.accounts.request" output-channel="channel.accounts.outbound.request">
<bean
class="notification.fuelnotification.infrastructure.transformer.common.AccountsRequestTransformer" />
</int:transformer>
<int:transformer id="accountResTf" method="transform"
input-channel="channel.accounts.outbound.reply" output-channel="channel.accounts.reply">
<bean
class="notification.fuelnotification.infrastructure.transformer.common.UnencryptedCardsResponseTransformer" />
</int:transformer>
<int:transformer id="errorLoggerTransformer"
method="logDetails" input-channel="channel.error">
<bean
class="notification.fuelnotification.infrastructure.config.amqp.ErrorChannelDetailLogger" />
</int:transformer>

Lucene Index: Missing documents

We have a pretty basic Lucene set up. We recently noticed that some documents aren't written to the index.
This is how we create the document:
private void addToDirectory(SpecialDomainObject specialDomainObject) throws IOException {
Document document = new Document();
document.add(new TextField("id", String.valueOf(specialDomainObject.getId()), Field.Store.YES));
document.add(new TextField("name", specialDomainObject.getName(), Field.Store.YES));
document.add(new TextField("tags", joinTags(specialDomainObject.getTags()), Field.Store.YES));
document.add(new TextField("contents", getContents(specialDomainObject), Field.Store.YES));
for (Language language : getAllAssociatedLanguages(specialDomainObject)) {
document.add(new IntField("languageId", language.getId(), Field.Store.YES));
}
specialDomainObjectIndexWriter.updateDocument(new Term("id", document.getField("id").stringValue()), document);
specialDomainObjectIndexWriter.commit();
}
This is how we create the analyzer and the index writer:
<bean id="luceneVersion" class="org.apache.lucene.util.Version" factory-method="valueOf">
<constructor-arg value="LUCENE_46"/>
</bean>
<bean id="analyzer" class="org.apache.lucene.analysis.standard.StandardAnalyzer">
<constructor-arg ref="luceneVersion"/>
</bean>
<bean id="specialDomainObjectIndexWriter" class="org.apache.lucene.index.IndexWriter">
<constructor-arg ref="specialDomainObjectDirectory" />
<constructor-arg>
<bean class="org.apache.lucene.index.IndexWriterConfig">
<constructor-arg ref="luceneVersion"/>
<constructor-arg ref="analyzer" />
<property name="openMode" value="CREATE_OR_APPEND"/>
</bean>
</constructor-arg>
</bean>
Indexing is done with a scheduled task:
#Component
public class ScheduledSpecialDomainObjectIndexCreationTask implements ScheduledIndexCreationTask {
private static final Logger logger = LoggerFactory.getLogger(ScheduledSpecialDomainObjectIndexCreationTask.class);
#Autowired
private IndexOperator specialDomainObjectIndexOperator;
#Scheduled(fixedDelay = 3600 * 1000)
#Override
public void createIndex() {
Date indexCreationStartDate = new Date();
try {
logger.info("Updating complete special domain object index...");
specialDomainObjectIndexOperator.createIndex();
if (logger.isDebugEnabled()) {
Date indexCreationEndDate = new Date();
logger.debug("Index creation duration: {} ms", indexCreationEndDate.getTime() - indexCreationStartDate.getTime());
}
} catch (IOException e) {
logger.error("Could update complete special domain object index.", e);
}
}
}
createIndex() is implemented as follows:
#Override
public void createIndex() throws IOException {
logger.trace("Preparing for index generation...");
IndexWriter indexWriter = getIndexWriter();
Date start = new Date();
logger.trace("Deleting all documents from index...");
indexWriter.deleteAll();
logger.trace("Starting index generation...");
long numberOfProcessedObjects = fillIndex();
logger.debug("Index written in " + (new Date().getTime() - start.getTime()) + " milliseconds.");
logger.debug("Number of processed objects: {}", numberOfProcessedObjects);
logger.debug("Number of documents in index: {}", indexWriter.numDocs());
indexWriter.commit();
indexWriter.forceMerge(1);
}
#Override
protected long fillIndex() throws IOException {
Page<SpecialDomainObject> specialDomainObjectsPage = specialDomainObjectRepository.findAll(new PageRequest(0, MAXIMUM_PAGE_ELEMENTS));
while (true) {
addToDirectory(specialDomainObjectsPage);
if (specialDomainObjectsPage.hasNextPage()) {
specialDomainObjectsPage =
specialDomainObjectRepository.findAll(new PageRequest(specialDomainObjectsPage.getNumber() + 1, specialDomainObjectsPage.getSize()));
} else {
break;
}
}
return specialDomainObjectsPage.getTotalElements();
}
There are about 2000 specialDomainObject instances and about 80 aren't written to the index (we checked this with Luke).
Is there anything that could cause the missing documents?
We found the problem: The default encoding of the operating system was not set to UTF-8.