#759: XmlOmitField.java
projectforge-business/src/main/java/org/projectforge/framework/xmlstream/XmlOmitField.java Java marker annotation — excludes a field from XmlStream XML serialization. Source: projectforge-business/src/main/java/org/projectforge/framework/xmlstream/XmlOmitField.java 39 lines · 9 code · 26 comments · 4 blank
Purpose: A zero-parameter marker annotation that tells the XmlStream framework to skip a field during XML serialization and deserialization. It is the XmlStream equivalent of Java's transient keyword and JAXB's @XmlTransient, but scoped exclusively to the ProjectForge XmlStream framework — leaving the field intact for Java serialization, JPA persistence, and other subsystems.
Architecture
The annotation itself is minimal — 3 lines of code,
@Target(FIELD),
@Retention(RUNTIME). Its power comes from the
consumers that check for its presence:
•
XmlObjectWriter.writeField() (
#758, line ~242):
if (field.isAnnotationPresent(XmlOmitField.class)) continue;
•
XmlObjectReader.read() (
#757, line ~471): skips fields annotated with
@XmlOmitField during deserialization
There is no logic in the annotation itself — it's a pure marker consumed reflectively by the reader/writer pair.
Why a Separate Annotation Instead of transient?
Java's transient keyword excludes a field from all serialization mechanisms — Java Serialization, XStream, XmlStream, JSON mappers, everything. This is often too broad:
Scenario: A field like computedHash should be cached in the HTTP session (Java serialization) but must not appear in XML exports (wasteful, misleading).
Solution: Make the field non-transient (so it participates in Java session serialization) and annotate it with @XmlOmitField (so XmlStream skips it). This gives per-framework control over serialization visibility.
Security example: password in PFUserDO. The field is transient (session safety) AND annotated with @XmlOmitField (XML safety). Even if someone removes transient for debugging, the annotation provides a second barrier preventing passwords from leaking into XML exports.
Contrast with @XmlField(defaultValue=...)
| Mechanism | When field is skipped | Use case |
@XmlOmitField | Always — regardless of value | Passwords, computed fields, temporary state, sensitive data |
@XmlField(defaultIntValue=0) | Conditionally — only when value equals the default | Size optimization: omit zero-values, empty strings, nulls |
The difference is semantic: @XmlOmitField says "this field has no business being in XML", while @XmlField(defaultValue=...) says "this field is sometimes redundant — skip it when it is". One is a hard policy, the other is a soft optimization.
Git History
868d6abb7 2025 → 2026 (copyright year update)
63081666f Source file headers: 2024→2025
b6092df09 Copyright 2023 → 2024
ab45d51fa Copyright 2001-2022 → 2001-2023
5f7ef41b8 Copyright 2021 → 2022
cd27dd997 package xstream → xmlstream (renamed to avoid confusion with XStream library)
ceb63e8a1 Source code header: (C) 2001-2021
7c79f1922 Copyright of source header → 2020
32f634b88 Optimize imports
dd5ca38ac CopyRight of all java file-header updated or created
9ebb88522 Initial commit
The annotation has remained unchanged since the initial commit — only copyright headers and one package rename (xstream → xmlstream). This stability reflects its design: a marker annotation with no parameters has no moving parts to break. The only meaningful change was cd27dd997 which renamed the package from xstream to xmlstream to avoid namespace collision with the XStream library (com.thoughtworks.xstream).
XmlStream Annotation Trio
| Annotation | File | Role |
@XmlField | #755 | Declares a field for serialization with name, type, default value, format, ordering |
@XmlObject | #756 | Declares a class as XML-serializable with alias |
@XmlOmitField | #759 | Excludes a field from serialization entirely |
Together these three annotations form the complete configuration surface of the XmlStream framework. @XmlObject enables a class for serialization, @XmlField configures individual fields, and @XmlOmitField selectively disables fields. This is simpler than JAXB (which has ~20 annotations) and more explicit than XStream's pure-convention approach.