Thanks. It is not that issue, the issue is still current in 2.3.1 and 2.1. I have put in a bug report via Jira

https://issues.apache.org/jira/browse/LUCENENET-170

Here's the test code for a console application which shows the problem

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using Lucene.Net.Search;

namespace TestSerialization
{
   class Program
   {
       static void Main(string[] args)
       {
           //build our sample query
           BooleanQuery queryPreSerialized = new BooleanQuery();
queryPreSerialized.Add(new TermQuery(new Lucene.Net.Index.Term("country","Russia")),BooleanClause.Occur.MUST); queryPreSerialized.Add(new TermQuery(new Lucene.Net.Index.Term("country","France")),BooleanClause.Occur.MUST); Console.WriteLine("Query pre serialisation: " + queryPreSerialized.ToString());

           //now serialize it
           BinaryFormatter serializer = new BinaryFormatter();
           MemoryStream memoryStream = new MemoryStream();
           serializer.Serialize(memoryStream, queryPreSerialized);

           //now deserialize
           memoryStream.Seek(0, SeekOrigin.Begin);
BooleanQuery queryPostSerialized = (BooleanQuery)serializer.Deserialize(memoryStream); Console.WriteLine("Query post deserialization: "+ queryPostSerialized.ToString());

           if (!queryPreSerialized.Equals(queryPostSerialized))
Console.WriteLine("Serialized and deserialized do not match - down to issues with the way Parameter objects (in BooleanClause.Occur are maintained");

           memoryStream.Close();

           Console.WriteLine("press enter to close");
           Console.Read();
       }
   }
}



Digy wrote:
Hi Moray,

There is an issue http://issues.apache.org/jira/browse/LUCENENET-100 that
may be related to your problem and it has been fixed with v2.1. Can you make
your tests with a newer version of Lucene.Net( such as 2.1 or 2.3.1 in
current trunk)?
DIGY

-----Original Message-----
From: Moray McConnachie [mailto:mmcco...@oxford-analytica.com] Sent: Friday, January 23, 2009 3:21 PM
To: lucene-net-user@incubator.apache.org
Subject: possible bug: serialization of BooleanClause / Occurs
(implementation of Parameter)

Please let me know if this would be a question better addressed to dev. I have not posted this as a bug issue on the incubator, because I'm not sure if it is a bug or I'm just missing something.

I'm upgrading from an earlier installation of Lucene.NET 1.x to using Lucene.NET 2.0.004.

Our application uses a client-server architecture. The client application serializes a Query object and sends it to the server. The server runs the query and returns results.

The client/server operation is handled using .NET remoting which uses standard .NET binary serialisation. This is very effective and fast in our application.

The issue I have in upgrading to v2 is that the occur member of a BooleanClause object is not being deserialized correctly, with the result that queries do not pass from client to server correctly.

occur is of type Occur, which inherits from Parameter, a class which supplies Enum-replacements.

On looking into the code, I do not see how objects inheriting from Parameter will ever correctly be deserialized, because there is a static collection of strings definining the enums in Parameter which won't get serialized.

I have been able to get round the issue by intercepting the serialisation and deserialisation of BooleanClause, constructing a temporary string variable, like this

private string _occurSerialized=null;

//HACK set up BooleanClause for serialisation
        [System.Runtime.Serialization.OnSerializing()]
internal void OnSerializingMethod(System.Runtime.Serialization.StreamingContext context)
        {
            _occurSerialized = occur.ToString();
        }

        [System.Runtime.Serialization.OnDeserialized()]
internal void OnDeserializedMethod(System.Runtime.Serialization.StreamingContext context)
        {
            switch (_occurSerialized.ToString())
            {
                case "+":
                    occur = Occur.MUST;
                    break;
                case "-":
                    occur = Occur.MUST_NOT;
                    break;
                default:
                    occur = Occur.SHOULD;
                    break;
            }
            _occurSerialized = null;
        }

However, this is bad in the long term since

a) if the enums ever change it will need to be rewritten, and

b) it is not general across other things that may need to be serialized which inherit from Parameter

I could do with someone who knows more about the fundamental structures in Lucene helping me out with this...

Thanks,
Moray





Reply via email to