сопоставление полей с собственной ссылкой в ​​JPA - PullRequest
5 голосов
/ 19 декабря 2011

Допустим, у нас есть класс сущности User.Пользователь может дружить с другими пользователями.Как я могу сопоставить это поле для сбора ссылок на себя, не создавая новый объект с именем Connection или не создавая несколько записей в базе данных?

@Entity
public class User {
...
@ManyToMany
private Collection<User> friends;
...
}

USER_ID-FRIEND_ID
1 - 2
2 - 1 (duplicate... I don't need it)

Ответы [ 4 ]

6 голосов
/ 19 декабря 2011

Ниже приведен снимок из моего кода для ElementEntity:

@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
private List<ElementEntity> children;

@JoinColumn(name = "ParentId", referencedColumnName = "ElementId")
@ManyToOne(fetch = FetchType.LAZY)
private ElementEntity parent;

Где в базе данных есть поля:

  • ElementId - первичный ключ;
  • ParentId связь с родителем
1 голос
/ 19 декабря 2011

Как минимум вам понадобится relational table.

Итак, у вас есть USER таблица и FRIENDS:

user_id friend_id
   1      2

Но ответ @ Божо намного лучше моего (neo4j).

1 голос
/ 19 декабря 2011

Вы не можете - вам нужны обе записи в базе данных.

На самом деле, для дружеских отношений я бы сказал, что графическая база данных, такая как neo4j, - это то, что нужно использовать.Там у вас есть два пользователя и просто добавить ребро "друзья".

0 голосов
/ 14 июля 2017

Ну, на самом деле вы можете.

Вы можете использовать аннотации, такие как @PreUpdate, @PrePersists, @PostUpdate и т. Д., Чтобы вручную преобразовать элементы коллекции.Таким образом, ваша сущность может отображать то, что вы хотите, в то время как в базе данных вы храните только необработанный текст.

Более приемлемой альтернативой будет использование аннотации @Convert, доступной начиная с jpa 2.1 (@UserType в hibernate).Он сообщает jpa преобразовывать поле в другой тип при каждом чтении / сохранении в базе данных.Для этого вам следует использовать аннотацию @Convert, указав и объект AttributeConverter.

Например

    public class Parent {
      @Id
      private Integer id;

      @Convert(converter = FriendConverter.class)
      private Set<Parent>friends;
    }

И класс конвертера, подобный следующему:

    @Component
    public class FriendConverter implements AttributeConverter<List, String>{
      @Autowired
      private SomeRepository someRepository;

      @Override
      public String convertToDatabaseColumn(List attribute) {
        StringBuilder sb = new StringBuilder();
        for (Object object : attribute) {
          Parent parent = (parent) object;
          sb.append(parent.getId()).append(".");
        }
        return sb.toString();
      }

      @Override
      public List convertToEntityAttribute(String dbData) {
        String[] split = dbData.split(".");
        List<Parent>friends = new ArrayList<>();
        for (String string : split) {
          Parent parent = someRepository.findById(Integer.valueOf(string));
          friends.add(accion);
        }
        return friends;
      }
    }

Этоглупая реализация, но она дает вам представление.

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

...