Какова лучшая практика для создания постоянства (скажем, с помощью Spring Boot или просто JPA или самого Hibernate) для модели данных, исходящей из неизменяемой зависимости? Типичные ограничения, такие как невозможность переопределить поле или то, что позволяют шаблоны, такие как Decorator, и то, что не замедляет мой прогресс. Я пробовал кое-что, но я всегда получаю результат, в котором необходимо либо изменить исходную модель (например, добавить аннотации, чтобы сделать ее нативно совместимой -> разветвление, которое я не хочу), либо написать тонну кода-обертки который слишком сильно скопировал бы оригинальную модель - но даже сейчас это не работает:
Я пытался
- Создание
JpaRepository
для исходного класса. Не работает, потому что приведение расширенного класса к родительскому классу не работает.
- Расширить исходный класс пользовательским классом, который получает необходимые аннотации, такие как
@Entity
, которые можно использовать в таком хранилище. Но проблемы здесь были
- что в исходном классе отсутствует аннотация
@Id
, которую можно исправить, используя новый идентификатор в расширенном классе, но
- данная модель также имеет непростую архитектуру, включая списки других классов, которые являются частью самой модели. Поэтому могут понадобиться другие аннотации, такие как
@ElementCollection
, которые нельзя добавить, поскольку переопределение полей невозможно.
- Скрытие с созданием нового поля с тем же именем в новом классе не работает:
- Ошибка типа
Could not determine type for: java.util.List, at table: yeah_this_one, for columns:[org.hibernate.mapping.Column(objects)]
указывает, что исходное поле не может быть полностью скрыто (изменили имя таблицы и столбца в новом классе, чтобы убедиться в этом).
- Так что, конечно, добавление
@ElementCollection
(которое, как говорят, решает эту проблему) здесь тоже не поможет.
@AttributeOverride
также не работает для переопределения аннотаций для установки идентификатора или других настроек, можно изменить только имя и столбец.
Я застрял в этом состоянии и мне интересно, является ли это вообще правильным подходом.
Настройка или то, что я ожидаю, чтобы работать из моего понимания:
Общая идея основана на этом учебнике REST по Spring Boot , который я попытался расширить с помощью модели из зависимости.
Предположим, что существует исходный класс модели Model
из зависимости, которую нельзя изменить. ModelEntity
будет расширенным классом, который будет действовать как способ втянуть модель в постоянство Spring.
В области зависимости исходный класс будет выглядеть так:
// Given dependency, not modifiable
@Some existing annotation
public class Model extends AnotherClassFromDep {
@more annotations
private IdLikeClassFromDep modelId;
//more complex attribute
@Nullable
private List<RefClassFromDep> objects = new ArrayList<>();
// more attributes, getter, setter etc.
}
В рамках моей программы:
В сочетании с этим небольшим дополнительным orm.xml
можно аннотировать оригинал Model
как MappedSuperclass
без его изменения (согласно https://stackoverflow.com/a/2516951/1844976).
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd" version="1.0">
<mapped-superclass class="package.name.of.original.Model">
</mapped-superclass>
</entity-mappings>
Это позволяет создать такой класс, который расширяет исходную модель POJO для добавления аннотаций JPA:
@Entity
public class ModelEntity extends Model {
// some @Id attribute is necessary, which should correspond to
// the already existing ID attribute from the original `Model`
// in the best case, but an additional one would work too
private @Id @GeneratedValue Long id;
// Different approaches to solve the List error from above, for
// instance hiding the original attribute
@ElementCollection
private List<RefClassFromDep> objects;
public ModelEntity(){
super();
}
}
В текущем состоянии проблемы мешают мне идти дальше. Но в целом я бы ожидал, что это сработает с JpaRepository
:
// of course, creating a JpaRepository with original `Model` wouldn't
// work, because it has no `@Entity`
public interface ModelRepository extends JpaRepository<ModelEntity, IdLikeClassFromDep> {
}
Таким образом, возможен фактический доступ к нему:
@Configuration
public class LoadDatabase {
@Bean
CommandLineRunner initDatabase(ModelRepository modelRepository) {
return args -> {
// depending on the implementation above, either create a
// Model and cast it or directly create a ModelEntity, set
// attriubtes and save it through the JpaRepository
modelRepository.save(model);
};
}
}
Мне могут помочь как более абстрактные, так и специфические идеи и комментарии, связанные с кодом. Спасибо!