Динамически добавлять поля в Hibernate Entity во время выполнения - PullRequest
2 голосов
/ 16 мая 2019

У меня есть приложение с настраиваемыми полями - пользователи в основном могут определить настраиваемое поле, выбрав тип поля и присвоив ему имя. Затем настраиваемые поля представляются как часть объекта, и данные, переданные этим полям, сохраняются в моей базе данных. В большинстве случаев мне удалось без проблем обработать их программно и с помощью обычных отображений гибернации (т. Е. Аннотированной коллекции @OneToMany). Однако в настоящее время я столкнулся с проблемой. Нам бы хотелось, чтобы эти пользовательские поля и их значения использовались для создания отчетов в режиме реального времени о «родительских» объектах. Значения настраиваемых полей отображаются как коллекции внутри родительских объектов, но они мне нужны для отчетов. Я создал представление, которое обеспечивает именно то, что мне нужно, со стороны SQL - Я последовал этому примеру, чтобы добавить динамическое вращение, и в результате запроса именно так я и хотел бы отобразить свою информацию . Конечно, не на следующих изображениях, но это по сути вывод, который у меня есть.

pivot1

pivot2

Представление возвращает полностью динамическое число столбцов, каждый из которых назван для настраиваемого поля и заполнен соответствующими данными для этой строки.

Проблема в том, что теперь я понятия не имею, как получить эту информацию с помощью Hibernate.

Я нашел документацию для обновления PersistentClass путем получения ClassMappings из конфигурации Hibernate:

Управление метаданными во время выполнения

//Get the existing mapping for AgreementsGrid from Configuration
PersistentClass gridMapping = configuration.getClassMapping(AgreementsGrid.class.getName());

//Define new Column
Column column = new Column();
column.setName("ESTIMATED_COST_OVERRUNS");
column.setNullable(true);
column.setUnique(false);
gridMapping.getTable().addColumn(column);

//Wrap the column in a value
SimpleValue value = new SimpleValue();
value.setTable(gridMapping.getTable());
value.setTypeName("string");
value.addColumn(column);

//Define new property for the AgreementsGrid class
Property prop = new Property();
prop.setValue(value);
prop.setName("customField1");
prop.setNodeName(prop.getName());
gridMapping.addProperty(prop);

//Build a new session factory for the new mapping
SessionFactory sessionFactory = configuration.buildSessionFactory();

Я только что понял, что это для Hibernate 3 и 4, и даже невозможно в Hibernate 5 (я использую 5.2.18).

Итак, я пытаюсь выяснить, как справиться с этим в Hibernate 5. У меня есть базовая сущность, сопоставленная с представлением, и во время выполнения мне нужно иметь возможность динамически добавлять к ней «поля», чтобы мой DAO могут динамически фильтровать информацию и обрабатывать сортировки / группировки.

Вот сущность, которую я имею на мой взгляд:

@Entity
@Table(name="AGREEMENTS_GRID")
public class AgreementsGrid implements Serializable {
    private static final long serialVersionUID = 1L;

    private Integer entityId;
    @Column(name="ENTITY_ID")
    @Id
    public Integer getEntityId() {
        return this.entityId;
    }
    public void setEntityId(Integer entityId) {
        this.entityId = entityId;
    }

    private Agreements agreement;
    @ManyToOne
    @JoinColumn(name = "AGREEMENT_ID", referencedColumnName = "ID", nullable = false)
    public Agreements getAgreement() {
        return this.agreement;
    }
    public void setAgreement(Agreements agreement) {
        this.agreement= agreement;
    }

    private BigDecimal expenditure;
    @Column(name = "EXPENDITURE", nullable = true, precision = 22, scale = 2)
    public BigDecimal getExpenditure() {
        return this.expenditure;
    }
    public void setExpenditure(BigDecimal expenditure) {
        this.expenditure = expenditure;
    }

    /*
     * Dynamic fields would theoretically go here and look like this,
     * for a custom field of type CURRENCY named 'Estimated Cost Overruns'
     */
    /*
    private BigDecimal customField1;
    @Column(name = "ESTIMATED_COST_OVERRUNS", nullable = true, precision = 22, scale = 2)
    public BigDecimal getCustomField1() {
        return this.customField1;
    }
    public void setCustomField1(BigDecimal customField1) {
        this.customField1 = customField1;
    }
    */

 }

Просто чтобы прояснить, я не могу отобразить эти поля во время компиляции. Они являются чисто пользовательскими и определяются исключительно пользователями. Во время выполнения я смогу узнать, какие настраиваемые поля существуют, поэтому я смог бы пройтись по ним и добавить их (как я надеялся сделать с помощью столбца добавления, как было показано выше), но я не могу знать перед развертыванием. Пользовательские поля также могут быть изменены в любой момент.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...