Skip to content

New feature: Strip persistent collections #93

Closed
@digulla

Description

@digulla

I have a scenario where entities are read in a database layer, serialized to JSON and then sent via JMS to a front end server. The front end has no connection to any database, hence no SessionFactory.

In order to avoid to have to add @JsonType annotations everywhere, I've enabled mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

This works until a PersistentCollection is serialized. This yields something like:

..., "types": ["...PersistentSet", {...}]

The frontend has the class (Hibernate has to be on the class path, or I couldn't access the Entity beans at all, thanks to all the annotations). The problem is that Jackson eventually calls PersistentSet.add() which then immediately throws LazyInitializationException( "could not initialize proxy - no Session" ).

So far the only solution I could find was to comment out if (!usesLazyLoading(property)) in PersistentCollectionSerializer and add this code to the serialize*() methods:

    if (_serializer == null) { // sanity check...
        throw new JsonMappingException("PersistentCollection does not have serializer set");
    }

    value = convertToJavaCollection(value); // Strip PersistentCollection

    _serializer.serializeWithType(value, jgen, provider, typeSer);

Here is the code for the new method:

private Object convertToJavaCollection(Object value) {
    if (!(value instanceof PersistentCollection) ) {
        return value;
    }

    if (value instanceof Set) {
        return convertToSet((Set<?>)value);
    }

    if (value instanceof List
        || value instanceof Bag
    ) {
        return convertToList((List<?>)value);
    }

    if (value instanceof Map) {
        return convertToMap((Map<?,?>)value);
    }

    throw new IllegalArgumentException("Unsupported type: " + value.getClass());
}

private Object convertToList(List<?> value) {
    return Lists.newArrayList(value);
}

private Object convertToMap(Map<?, ?> value) {
    return Maps.newHashMap(value);
}

private Object convertToSet(Set<?> value) {
    return Sets.newHashSet(value);
}

It would be nice if you could integrate this as a new feature into your code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions