2016-01-04 1 views
0

Я реализую то, что составляет файловую систему онлайн, поддерживаемую базой данных SQL через JPA. Для иерархии каталогов я создал объект, который выглядит следующим образом:Насколько я могу масштабировать коллекцию JPA (карта или список)

@Entity 
@Table(name = "PATH") 
public class Path extends BaseObject implements Serializable { 

    @Column(nullable = false) 
    private String name; 

    @ManyToOne 
    private BaseObject reference; 

    @OneToMany(fetch = FetchType.LAZY, orphanRemoval = true) 
    @MapKey(name = "name") 
    private Map<String, Path> members; 

    @ManyToOne 
    private Path parent; 

    //etc 

Это работает удивительно хорошо. Корневым узлом является Путь экземпляр, где parent is null. С помощью этой схемы я могу делать обходы дерева вверх и вниз и искать как можно безболезненно.

Проблема в том, насколько это можно масштабировать. Например, один из моих корневых экземпляров Path будет иметь один член для каждого пользователя системы. Это нормально для нескольких десятков или даже нескольких сотен пользователей, что происходит, если мой сайт привлекает десятки или даже сотни тысяч пользователей?

Если бы я должен был я мог отказаться от членов колонки и найти узлы членов с SQL SELECT операции, но я не хочу этого делать. Есть ли какие-либо рекомендации, чтобы определить, насколько велика эта Карта Структура должна быть до того, как она станет непрактичной?

ответ

1

Ассоциация members, по умолчанию, ленив. Поэтому при загрузке Path ничего плохого не произойдет, пока ... вы не начнете использовать это поле members (т. Е. Вызовите любой метод на нем). Тогда тысячи детей будут загружены в память, и это не будет хорошо масштабироваться. Но использование выделенного запроса не будет лучше: тысячи детей также будут загружены в память.

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

Итак, я бы выбрал эту слишком опасную ассоциацию OneToMany и использовал специальные запросы для извлечения необходимых вам детей в срезах. То, что меня больше беспокоит, - это ссылка на родителя. Поскольку вы определили их как загруженные (это по умолчанию для ассоциаций toOne), каждый раз, когда вы загружаете путь, JPA будет загружать своего родителя, его дедушку и бабушку, а также ее прадедушку и т. Д. До корня. Это может быть проблематично, если ваше дерево глубокое. Вам лучше определить ассоциацию как ленивую (я делаю это для всех всех ассоциаций).

И, наконец, обратите внимание, что неправильное отображение. У вас есть двунаправленную связь здесь, и OneToMany members Таким образом, обратная сторона ManyToOne parent, поэтому он должен быть аннотированный с

@OneToMany(mappedBy = "parent", orphanRemoval = true) 

 Смежные вопросы

  • Нет связанных вопросов^_^