Hello everyone,
I'm dealing with a project that has a complex setup, and I'm trying to
simplify it. Our application allows users to establish Conditions or
Filters in the UI. These Conditions/Filters are stored in a database and
can be used to limit database queries using WHERE conditions.
Interestingly, these filters can be built recursively from other filters.
Our current structure involves DTO classes marked with Jackson annotations,
which build a hierarchy. This hierarchy is mapped into business objects,
despite not having real business logic. These are later converted into
database DTOs. The system is quite intricate as it spans across three
layers - REST, Domain, and ORM Mapper. Additionally, the code, written two
years ago by another developer, extensively uses Jackson Annotations, which
increases the complexity and makes it difficult for me to understand.
Here are the two code snippets for the REST DTOs and the ORM Mapper:
REST DTOs:
java
@JsonTypeInfo(use = DEDUCTION) // No idea why DEDUCTION was used here but
JsonTypeInfo.Id.NAME, below...
@JsonSubTypes({
@Type(AndDto.class),
@Type(OrDto.class),
@Type(ConditionDto.class),
@Type(FieldDto.class),
@Type(LabelDto.class)
})
public interface ExpressionDto {
}
ORM Mapper:
java
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = AndDbDto.class, name = "and"),
@JsonSubTypes.Type(value = OrDbDto.class, name = "or"),
@JsonSubTypes.Type(value = ConditionDbDto.class, name =
"condition"),
@JsonSubTypes.Type(value = FieldDbDto.class, name = "field"),
@JsonSubTypes.Type(value = LabelDBDto.class, name = "label")
})
public interface ExpressionDbData {
}
I'm faced with the task of integrating about 15 more logical operators into
the model, on top of the two already present - Equals for Field and
Contains for Labels. Incorporating these operators would significantly ramp
up the complexity of the existing model.
Each field type is linked to a data type - Text, Number, or Date. Each data
type should support its specific logical comparison operators:
TEXT: EQUAL, EQUAL_IGNORE_CASE, NOT_EQUAL, START_WITH, ENDS_WITH,
CONTAINS
NUMBER: EQUAL, NOT_EQUAL, GREATER, SMALLER, GREAT_EQUAL, SMALLER_EQUAL
DATE: EQUAL, BEFORE, AFTER, BEFORE_OR_EQUAL, EQUAL_OR_AFTER
I'm searching for a more straightforward yet valid method to accept these
conditions/filters from the frontend, store them in the database, and later
apply them to database queries. At present, we're achieving this with a
custom JPA CriteriaBuilder.
Could using a custom Serializer / Deserializer or maybe an
AttributeConverter be helpful in this case?
Something like this maybe:
@Override
public void serialize(AndExpression value, JsonGenerator gen,
SerializerProvider provider) throws IOException {
gen.writeStartObject();
gen.writeStringField("type", "and");
gen.writeFieldName("expressions");
gen.writeStartArray();
for (Expression expression : value.getExpressions()) {
gen.writeObject(expression);
}
gen.writeEndArray();
gen.writeEndObject();
}
}
public class AndExpressionDeserializer extends
StdDeserializer<AndExpression> {
public AndExpressionDeserializer() {
super(AndExpression.class);
}
@Override
public AndExpression deserialize(JsonParser p, DeserializationContext
ctxt) throws IOException, JsonProcessingException {
JsonNode node = p.getCodec().readTree(p);
JsonNode expressionsNode = node.get("expressions");
List<Expression> expressions = new ArrayList<>();
for (JsonNode expressionNode : expressionsNode) {
Expression expression =
p.getCodec().treeToValue(expressionNode, Expression.class);
expressions.add(expression);
}
return new AndExpression(expressions);
}
}
I'm not sure, and I'm open to suggestions. Currently, I'm using the latest
versions of Java and Frameworks - Java 20, Hibernate 6.2, and Quarkus 3.x,
so, for instance, I could use Sealed classes if it would help...
Thanks in advance,
Marcus
p.s.: Posted this again as my earlier message did not appear. Excuse me if
this appears as a duplicate.
--
You received this message because you are subscribed to the Google Groups
"jackson-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/jackson-user/911c4011-02ee-477e-8967-9dbbc0043ef1n%40googlegroups.com.