JPA объекты и идентификаторы таблиц в виде строки - PullRequest
0 голосов
/ 21 июня 2019

Я работаю с MySQL, и есть таблица, в которой есть данные json, относящиеся к идентификаторам в других таблицах, а не промежуточные таблицы

В настоящее время есть 3 таблицы: Клиенты, Активы и Таблица XXX, которые имеют 3 столбца: id, name и myData. Вот пример строки:

1, "Some name",

[
    {"customerId": 1, "assets": {"active": [10, 12, 13], "inactive": [15, 16]}}",
    {"customerId": 2, "assets": {"active": [40, 42], "inactive": [19]}}"

]

Кстати, я не могу изменить дизайн :(

Вот сущности:

@Table(name = "xxx")
class XXX {
   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   @Column(name = "id")
   private Long id;
   private String name;
   String myData;
}

@Table(name = "assets")
class Asset {
   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   @Column(name = "id")
   private Long id;
   private String name;
}

@Table(name = "customers")
class Customer {
   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   @Column(name = "id")
   private Long id;

   private String name;
}

Однако я бы хотел, чтобы сущность XXX правильно отобразила сущности и имела данные о клиентах и ​​активах, аналогичные приведенным ниже:

@Table(name = "xxx")
class XXX {
   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   @Column(name = "id")
   private Long id;
   private String name;
   //maybe some awesome annotation here?
   List<CustomerAssetsItem> customerAssetsItemsActive;

   //maybe some awesome annotation here?
   List<CustomerAssetsItem> customerAssetsItemsInactive;
}

где CustomerAssetsItem будет выглядеть так:

class CustomerAssetsItem {
   Customer customer;
   List<Asset> assets;
}

Возможно ли это с JPA? Или я должен просто создать новый сервис, который анализирует строку json, выполнить все запросы, которые мне нужны, чтобы построить иерархию? Спасибо!

1 Ответ

0 голосов
/ 22 июня 2019

Возможно, см. Этот пример: Преобразователь атрибутов JSON

Все, что вам нужно сделать, это предоставить AttributeConverter, который отображает строку JSON в ваш список или что-то еще.

На вашей сущности вы должны аннотировать класс конвертера через @Converter

@Table(name = "xxx")
class XXX {
   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   @Column(name = "id")
   private Long id;
   private String name;

   @Converter(converter = CustomerAssetsConverter.class)
   List<CustomerAssetsItem> customerAssetsItems;
}

И вы должны предоставить свой собственный конвертер, это всего лишь черновик. Вам необходимо добавить объект сопоставления JSON. Также, если вы хотите разрешить ссылку на идентификатор клиента в JSON, вам нужен собственный десериализатор, который для сопоставлений customerId: 1 выполняет запрос для получения этого клиента. См. Этот пример: Пользовательский десериализатор Джексона

Вы , возможно, не захотите разрешать ссылки , поскольку они могут привести к большому количеству запросов, а также вам, скорее всего, потребуется настроить множество параметров, чтобы они не заканчивались бесконечным циклом.

Я рекомендую включить кэширование второго уровня и использовать @Transactional соответствующим образом.

@Converter
public class CustomerAssetsConverter implements AttributeConverter<CustomerAssetsItem, String> {

    //Add object mapper and repository

    @Override
    public String convertToDatabaseColumn(CustomerAssetsItem item) {
        String itemJSON = null;
        try {
            itemJSON = objectMapper.writeValueAsString(item);
        } catch (final JsonProcessingException e) {

        }
        return itemJSON;
    }

    @Override
    public Map<String, Object> convertToEntityAttribute(String itemJSON) {
        CustomerAssetsItem item = null;
        try {
            item = objectMapper.readValue(itemJSON, CustomerAssetsItem.class);
        } catch (final IOException e) {

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