Announcement Announcement Module
Collapse
No announcement yet.
Spring Data Graph and EJB3 - Serialization Problem Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring Data Graph and EJB3 - Serialization Problem

    Hi everyone,

    We actually evaluate Spring Data Graph, whether it make sense to use it for our project.

    I despair at the following problem:
    Sending a domain object via a Stateless Session Bean (EJB3) - remotely or locally - to a client application (also implements the domain class) does work, but there must be a problem with serialization, because the attributes of the domain object has null for each attribute on client side.

    I think during serialization, the attributes can't be copied to the new object on client side, because the domain object on server side is coupled with the Interface NodeBacked? Because if I initialize another object of the domain class an fill in the attributes and then send it to the client, it works fine.

    More Information with coding examples:

    Domain class on server and client side: Product.java
    Code:
    @NodeEntity
    public class Product implements Serializable{
    
        private static final long serialVersionUID = 3371733444426178897L;
    
        @Indexed
        long id;
    
        @Indexed(fulltext = true, indexName = "productNameIndex")
        String name;
    
        public Product() {
        	
        }
        
        public Product(long id, String name) { 
        	this.id = id;
        	this.name = name; 
        }
        
        public long getId()
        {
            return id;
        }
        
        public String getName()
        {
            return name;
        }
        
        public void setName(String name)
        {
            this.name = name;
        }
    }
    server side: GraphService
    Code:
    @Service(value="graphService")
    public class GraphServiceImpl implements GraphService{
    	
        @Autowired GraphDatabaseContext ctx;
        @Autowired GraphRepository repository;
        @Autowired ProductRepository productRepository;
        
        @Transactional
        public Product getCopiedProduct(long id) {
        	Product product = productRepository.findByPropertyValue("id", id);
            //works fine - attribute values are available when send to client via ejb
            Product copiedProduct = new Product(product.getId(), product.getName());
            return copiedProduct;
        }
        
        @Transactional
        public Product getProduct(long id) {
        	Product product =  productRepository.findByPropertyValue("id", id);
        	System.out.println(product.getId()); //works fine - attribute values are available
        	System.out.println(product.getName()); //works fine - attribute values are available
            //but when send to client (serialized via ejb) - attributes are null
            return product; 
        }
    }
    server side: EJB
    Code:
    @Stateless
    @Interceptors(SpringBeanAutowiringInterceptor.class)
    public class MyRemoteInterfaceBean implements MyRemoteInterface {
    
        @Autowired
        private GraphService graphService;
        
        public Product getCopiedProduct(long id) {
            return graphService.getCopiedProduct(id); //works fine
        }
        
        public Product getProduct(long id) {
            return graphService.getProduct(id); // null in attributes when at client
        }
    }
    The client test code
    Code:
     MyRemoteInterface bean = (MyRemoteInterface) ctx.lookup("MyRemoteInterfaceBean/remote");
                
                //Create product
                bean.createProduct(1, "MyFirstProduct"); //works fine
                
                //Load created product
                Product p1 = bean.getProduct(1); //No Exceptions
                System.out.println(p1.getName()); //but null
                System.out.println(p1.getId()); //but null
    
                //Load created product (copied)
                Product cp1 = bean.getCopiedProduct(1);
                System.out.println(cp1.getName()); //worls fine
                System.out.println(cp1.getId()); //works fine
    As you can see, the different between Product Object and copied Product Object is the connetion to interface NodeBacked during runtime. So Serialization doesn't work correctly I think.

    Can you help me?
    Last edited by stomat06; Jun 15th, 2011, 09:09 AM.

  • #2
    Your problems is not related to EJB3, just to serialization.

    Haven't looked into serialization right now, but you're right. Do you have a neo4j store on the client side?

    The fields of SDG entities are directly mapped through to the nodes of the graph store (no data stored actually in the fields).

    Could you please try the following:
    Create a new instance of the entity inside your session bean (don't persist it) and copy the properties into it. Then transmit it over the wire.
    That might work.

    Serialization is a tough question, not so much writing out the entity in a correct format but rather what happens with during deserialization.
    Because if there is a graph-store it should try to reattach the node to the graph (which might suceed, but also might point to a completly different node - different id's).

    Will have to think about that.

    How urgent is serializing java domain objects directly over the wire? Could you also using a more usecase oriented data structure that just contains just the data needed (or use xml/json as intermediate format)?

    Cheers

    Michael

    Comment


    • #3
      Hi Michael,

      thx for your comments!

      Do you have a neo4j store on the client side?
      Yes I have.

      Could you please try the following:
      Create a new instance of the entity inside your session bean (don't persist it) and copy the properties into it. Then transmit it over the wire.
      That might work.
      As mentioned above in my first post, I've already tested that, and you're right, it works this way. (See coding extraction GraphService method "getCopiedProduct").

      Could you also using a more usecase oriented data structure that just contains just the data needed (or use xml/json as intermediate format)?
      Yes we have to think about that. But in some of our use cases it makes sense to just send the Domain Object over the wire.

      So there is no way (with the actual release of spring data graph) to adjust the linkage between Domain Object and NodedBacked, so that it is possible to distribute the loaded Domain Object via EJB3 (so via Serialization)? (and without copy its attributes to annother Domain Object without this linkage)

      Best regards!

      Comment


      • #4
        Sorry was in a hurry, didn't read your post thouroughly enough.

        The problem with the local store copy is that you have to keep it in sync with the server one (i.e. by using HA or online-backup). It mustn't differ in any node or relationship-id from the original store. Otherwise you can't map the domain object -> what you could do is to just transfer its indexed properties (unique) and retrieve the domain-entity from the client-side graph-store.

        So you don't have to serialize the whole object. Just either the node-id (when the stores are in sync) or the unique indexed properties (for looking up the entity).

        Hope I understood your intentions correctly.

        Michael

        Comment


        • #5
          The graph store is only on server-side. On client side there are only the java domain classes availbale to instatiate the received objects. I've tried following: Accessed the stateless session bean from within the server app (so same graph store etc.). But with same results. Again it only works if i copy the object and then send it via the bean (kind of an unlink between NodeBacked and the original object).

          I think we have to use something like JAXB/JSON to send the object to the client and so avoid the serialization problem.

          Thanks.

          Comment

          Working...
          X