У меня есть следующая проблема связи сущностей. "Игра" должна иметь два (и только два) объекты "Команды". У "Команды" может быть много "Игр"
Это, насколько я вижу, является отношениями Two-Many. Однако... Я не знаю, как смоделировать это в JPA. Например, я собирался сделать что-то вроде этого...
@Entity
public class Team extends BaseObject {
private Long id;
private Set<Game> games;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {return id;}
public void setId(Long id) {this.id = id;}
@OneToMany(mappedBy = "game")
public Set<Game> getGames() {return games;}
public void setGames(Set<Game> games) {this.games = games;}
}
@Entity
public class Game extends BaseObject {
private Long id;
private Team team1;
private Team team2;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {return id;}
public void setId(Long id) {this.id = id;}
@ HERE IS THE PROBLEM - WHAT ANNOTATION DO I USE?
public Team getTeam1() {return team1;}
public void setTeam1(Team team1) {this.team1 = team1;}
@ HERE IS THE PROBLEM - WHAT ANNOTATION DO I USE?
public Team getTeam2() {return team2;}
public void setTeam2(Team team1) {this.team2 = team2;}
}
Но, как Вы видите, я не уверен, как соединить таблицы со стороны аннотации. Кто-либо когда-либо делал что-то вроде этого прежде? Какие-либо идеи, справка?
спасибо очень!
Я бы хотел, чтобы кто-нибудь придумал потрясающее решение, но это непростая ситуация, в которой я никогда не мог найти очень хороший способ составить карту. Ваши варианты включают в себя:
Измените способ моделирования отношений. Например, у вас может быть что-то вроде:
@Энтититити.
общественный класс Принадлежность к игре
Команда;
Игровая игра;
int gamePosition; // Если для вас важно отслеживание команды 1 против команды 2
}
, а затем Игра
имеет Коллекция
, т.е. вы моделируете ее как много-много-много. Игра
все еще может иметь удобные методы для настройки команд 1 и 2 и т.д. (бизнес-логика, чтобы закрепить, что есть только 2 команды, как бы это ни было сделано), но они переносятся обратно в коллекцию Collection
, используемую в спящем режиме.
Отказаться от двунаправленности отношений - выбрать одно направление (Игра
→ Команда
кажется наиболее подходящим) и вздремнуть только в этих отношениях. Поиск Игры
в которых участвует Команда
становится операцией из вашего DAO и т.д., а не тем, что доступно из самого Команды
:
публичного класса GameDAO {
....
публичная коллекция <Игра> игрыForTeam(Team t) {
....
Запрос q = session.createQuery("FROM Game WHERE team1 = :team OR team2 = :team");
q.setParameter("команда", t);
return q.list();
}
}
или что-то подобное...
Продолжайте движение по маршруту, но "жульничайте" в конце команды
. Свойства на стороне Игры
должны быть отображены как нормальные многопользовательские отношения; затем используйте mappedBy
в конце Team
, чтобы указать, что Игра
'контролирует' отношения.
public class Team {
...
@OneToMany(mappedBy="team1")
private Set team1Games;
@OneToMany(mappedBy="team2")
private Set team2Games;
и затем имеют свойство удобства для вашего API (team1Games
и team2Games
только для использования в спящем режиме):
@Transient
public Set getGames() {
Set allGames = new HashSet(team1Games);
allGames.addAll(team2Games);
// Или используйте Google-коллекции Sets.union() для получения бонусных очков.
вернуть AllGames;
}
так что для абонентов вашего класса прозрачно, что есть 2 свойства.
PC-Lint может помочь, это как Findbugs для C++. Это коммерческий продукт, но есть гарантия возврата 30 денег.
-121--3223146- Можно предоставить собственную функцию сортировки list.sort ()
:
-121--789211-Метод sort () принимает необязательные аргументы для управления сравнениями.
cmp задает пользовательскую функцию сравнения двух аргументов (перечислять предметов), которая должна возвращать отрицательное, нулевое или положительное число в зависимости от того, считается ли первый аргумент меньшим, равным или большим, чем второй аргумент:
cmp = lambda x, y: cmp (x.lower (), y.lower ())
. Значение по умолчанию -Нет
.key указывает функцию одного аргумента, который используется для извлечения ключа сравнения из каждого элемента списка:
key = str.lower
. Значение по умолчанию -Нет
.reverse является логическим значением. Если установлено значение True, элементы списка сортируются так, как если бы каждое сравнение было отменено.
В общем случае процессы преобразования ключей и обратного преобразования намного быстрее, чем задание эквивалентной функции cmp. Это происходит потому, что cmp вызывается несколько раз для каждого элемента списка, в то время как клавиша и обратная клавиша касаются каждого элемента только один раз.
Я думаю, что у вас есть две отношения один ко многим, а не одно два ко многим.
У вас есть отношения @Onetomany (я полагаю, игра имеет отношения @manytoOne с командой), мой совет:
Используйте инкапсуляцию, чтобы получить вашу цель
@Entity
public class Team {
private Game game1;
private Game game2;
private List<Game> gameList = new ArrayList<Game>();
public void setGame1(Game game1) {
// You can use index 0 to store your game1
if(getGameList().size == 0)
getGameList().add(game1);
else
getGameList().set(0, game1);
}
@Transient
public Game getGame1() {
if(getGameList().size() == 0)
return null;
return getGameList().get(0);
}
public void setGame2(Game game2) {
// You can use index 1 to store your game2
switch(getGameList().size()) {
case 0:
getGameList().add(null);
getGameList().add(game2);
break;
case 1:
getGameList().add(game2);
break;
case 2:
getGameList().set(1, game2);
break;
}
}
@Transient
public Game getGame2() {
if(getGameList().size() < 2)
return null;
return getGameList().get(1);
}
@OneToMany
@JoinColumn(name="TEAM_ID")
public List<Game> getGameList() {
return this.gameList;
}
}
знать, что иногда вы должны сделать свою работу в манере. Таким образом, инкапсуляция может быть ключом к вашему вопросу.
С уважением,
Подумайте, что произойдет, если в ваших играх будет первый игрок - команда (выбранная из списка команд), а второй игрок - компьютер (выбран из списка компьютеров):
Если вы теперь замените «компьютер» как игрока другой «командой», вы получите два внешних ключа в таблице команд.
Мой JPA немного устарел, но я считаю, что вы моделируете отношения внешнего ключа с помощью аннотации @OneToOne
, например:
@OneToOne(cascade = {CascadeType.ALL}, optional = false)
@JoinColumn(name = "team1")
и второй:
@OneToOne(cascade = {CascadeType.ALL}, optional = false)
@JoinColumn(name = "team2")