我想将休眠搜索@IndexingDependency
与 a一起使用,PropertyBridge
但我似乎无法使其工作。
我收到此错误:
Hibernate ORM mapping: type 'com.something.Person': path '.currentStatus':
failures:
- HSEARCH700020: Unable to find the inverse side of the association on type
'com.something.Person' at path '.currentStatus<no value extractors>'. Hibernate Search
needs this information in order to reindex 'com.something.Person' when
'com.something.Status' is modified. You can solve this error by defining the inverse
side of this association, either with annotations specific to your integration
(@OneToMany(mappedBy = ...) in Hibernate ORM) or with the Hibernate Search
@AssociationInverseSide annotation. Alternatively, if you do not need to reindex
'com.something.Person' when 'com.something.Status' is modified, you can disable
automatic reindexing with @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW)
不知道我做错了什么,或者我想做的事情是不可能的。感谢您的帮助。
以下是涉及的文件。
人物类
@Entity
@Table
@Indexed
public class Person {
@OneToMany(mappedBy = "patient", cascade = CascadeType.ALL)
private Set<Status> status = new HashSet<>();
@Transient
@StatusBinding(fieldName = "currentStatus")
@IndexingDependency(derivedFrom = @ObjectPath(@PropertyValue(propertyName = "status")))
public Status getCurrentStatus() {
return this.status.stream()
.filter(it -> it.getDate().isAfter(LocalDate.now()))
.max(Comparator.comparing(Status::getDate))
.orElse(null);
}
}
状态绑定.class
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD})
@PropertyMapping(processor = @PropertyMappingAnnotationProcessorRef(type = StatusBinding.Processor.class))
@Documented
public @interface StatusBinding {
String fieldName() default "";
class Processor implements PropertyMappingAnnotationProcessor<StatusBinding> {
@Override
public void process(PropertyMappingStep mapping, StatusBindingannotation, PropertyMappingAnnotationProcessorContext context) {
StatusBinderbinder = new StatusBinder();
if (!annotation.fieldName().isBlank()) binder.setFieldName(annotation.fieldName());
mapping.binder(binder);
}
}
}
StatusBinder.class
public class StatusBinder implements PropertyBinder {
@Setter private String fieldName = "mainStatus";
@Override
public void bind(PropertyBindingContext context) {
context.dependencies()
.use("status")
.use("date")
.use("note");
IndexSchemaObjectField mainStatusField = context.indexSchemaElement().objectField(this.fieldName);
context.bridge(Status.class, new StatusBridge(
mainStatusField.toReference(),
mainStatusField.field("status", context.typeFactory().asString()).toReference(),
mainStatusField.field("date", context.typeFactory().asLocalDate()).toReference(),
mainStatusField.field("note", context.typeFactory().asString()).toReference()
));
}
private static class StatusBrige implements PropertyBridge<Status> {
private final IndexObjectFieldReference mainStatusField;
private final IndexFieldReference<String> statusField;
private final IndexFieldReference<LocalDate> dateField;
private final IndexFieldReference<String> noteField;
public StatusBrige(
IndexObjectFieldReference mainStatusField,
IndexFieldReference<String> statusField,
IndexFieldReference<LocalDate> dateField,
IndexFieldReference<String> noteField
) {
this.mainStatusField = mainStatusField;
this.statusField = statusField;
this.dateField = dateField;
this.noteField = noteField;
}
@Override
public void write(DocumentElement target, Status mainStatus, PropertyBridgeWriteContext context) {
DocumentElement statutElement = target.addObject(this.mainStatusField);
statutElement.addValue(this.statusField, mainStatus.getStatus);
statutElement.addValue(this.dateField, mainStatus.getDate());
statutElement.addValue(this.noteField, mainStatus.getNote());
}
}
}