I thought that was obvious, but you can have two instances of the same class that behave differently. That’s why equals(Object)
exists, and isCompatibleWith
defaults to calling equals
.
Two instances generally behave differently when using a ValueBinder
, and there’s an example in this section of the documentation.
Even without a ValueBinder
, there are cases where Hibernate Search is not aware of how the bridges are constructed at all, and thus it cannot determine whether they will behave the same way.
For example you could have this:
public class BooleanAsStringBridge implements ValueBridge<Boolean, String> {
private final String trueAsString;
private final String falseAsString;
public BooleanAsStringBridge(String trueAsString, String falseAsString) {
this.trueAsString = trueAsString;
this.falseAsString = falseAsString;
}
@Override
public String toIndexedValue(Boolean value, ValueBridgeToIndexedValueContext context) {
if ( value == null ) {
return null;
}
return value ? trueAsString : falseAsString;
}
}
With two instances declared as CDI beans:
public class BridgeFactory {
@Produces
@Named("truefalse")
public BooleanAsStringBridge createBooleanAsTrueFalseBridge() {
Order order = new Order(product, shop);
return new BooleanAsStringBridge("true", "false");
}
@Produces
@Named("yesno")
public BooleanAsStringBridge createBooleanAsYesNoBridge() {
Order order = new Order(product, shop);
return new BooleanAsStringBridge("yes", "no");
}
}
And the bridge assigned separately to a field in NodeDocument
and NodeFolder
:
@Entity
@Indexed
public class NodeBase {
// ...
private final boolean active;
// ...
public boolean isActive() {
return active;
}
// ...
}
@Entity
@Indexed
public class NodeDocument extends NodeBase {
// ...
@GenericField(valueBridge = @ValueBridgeRef(name = "truefalse"))
@Override
public boolean isActive() {
return active;
}
// ...
}
@Entity
@Indexed
public class NodeDocument extends NodeBase {
// ...
@GenericField(valueBridge = @ValueBridgeRef(name = "yesno"))
@Override
public boolean isActive() {
return active;
}
// ...
}
And it could get even weirder: even when Hibernate Search itself calls the default constructor of the bridge, there’s no guarantee this constructor will always initialize the bridge to the same values. For example I could do this:
public class IntWithOffsetValueBridge implements ValueBridge<Integer, Integer> {
private static final AtomicInteger counter = new AtomicInteger(0);
private final int offset;
public IntWithOffsetValueBridge() {
offset = counter.incrementAndGet();
}
@Override
public Integer toIndexedValue(Integer value, ValueBridgeToIndexedValueContext context) {
return value + offset;
}
@Override
public boolean isCompatibleWith(ValueBridge<?, ?> other) {
return getClass().equals(other.getClass()) && offset == ((IntWithOffsetValueBridge)other).offset;
}
}
So, indeed, those are not the simplest use cases. But my point is: we just can’t assume that two instances of a same class behave the same.