Help with relationships between tables! The idea is this:

  • there is a user ( user sign)
  • there is a room (plate room )
  • there is a message ( message sign)

Links:

  • user and room - one to many;
  • one-to-many room and message;
  • User and message - one to many.

Each user can create a room, but it is not necessary where other users will exchange messages and he is in the same number. It can have several rooms, and the room is only 1 creator, but many users can correspond in it. The message in turn stores the ID of the room and the user who sent it, as well as the value.

The problem is that I can not properly make connections, or rather, how to program it on Java in hibernate. Below the code, please tell me how to properly implement the connection.

User;

 package ua.samuliak.messenger.entity; import org.hibernate.annotations.GenericGenerator; import javax.persistence.*; import java.util.HashSet; import java.util.Set; @Entity @Table(name = "\"user\"") public class User { @Id @GeneratedValue(generator = "increment") @GenericGenerator(name = "increment", strategy = "increment") private Long id; @Column(name = "id_room") private Long room; @Column(nullable = false, length = 20) private String login; @Column(nullable = false, length = 20) private String password; @Column(length = 2) private String country; @Column(length = 2) private Integer age; @Column(length = 25) private String occupation; @OneToMany(mappedBy = "user") private Set<Room> rooms = new HashSet<Room>(); @OneToMany(mappedBy = "user_mes") private Set<Message> messages = new HashSet<Message>(); public User() {} public User(String login, String password, String country) { this.login = login; this.password = password; this.country = country; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Long getRoom() { return room; } public void setRoom(Long room) { this.room = room; } public String getLogin() { return login; } public void setLogin(String login) { this.login = login; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getOccupation() { return occupation; } public void setOccupation(String occupation) { this.occupation = occupation; } // public Set<Room> getRooms() { // return rooms; // } // // public void setRooms(Set<Room> rooms) { // this.rooms = rooms; // } } 

PS The last 2 methods are commented out in the user nameplate, because it gives an error

Room:

 package ua.samuliak.messenger.entity; import org.hibernate.annotations.GenericGenerator; import javax.persistence.*; import java.util.HashSet; import java.util.Set; @Entity @Table(name = "room") public class Room { @Id @GeneratedValue(generator = "increment") @GenericGenerator(name = "increment", strategy = "increment") private Long id; @Column(nullable = false, length = 30) private String title; @ManyToOne @JoinColumn(name = "user_id") private User user; @OneToMany(mappedBy = "room") private Set<Message> messages = new HashSet<Message>(); public Room() {} public Room(String title, User user) { this.user = user; this.title = title; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } } 

Message:

 package ua.samuliak.messenger.entity; import org.hibernate.annotations.GenericGenerator; import javax.persistence.*; @Entity @Table(name = "message") public class Message { @Id @GeneratedValue(generator = "increment") @GenericGenerator(name = "increment", strategy = "increment") private Long id; @ManyToOne @JoinColumn(name = "room_id") private Room room; @ManyToOne @JoinColumn(name = "user_id") private Room user_mes; @Column(nullable = false) private String value; public Message() {} public Message(Room room, String value) { this.room = room; this.value = value; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Room getRoom() { return room; } public void setRoom(Room room) { this.room = room; } public Room getUser_mes() { return user_mes; } public void setUser_mes(Room user_mes) { this.user_mes = user_mes; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } } 

    1 answer 1

    You are clearly missing another sign in which users logged into the room / chat will be stored. I propose to use a simplified example of the project (well, as far as I could understand your idea). I used Spring Data and Spring Boot to quickly launch an application. The project is started by the spring-boot:run command. Project ID on Github .

    pom.xml

     <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <groupId>org.mxbyrd</groupId> <artifactId>spring-data-531907</artifactId> <version>0.1.0</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.5.RELEASE</version> </parent> <properties> <java.version>1.8</java.version> </properties> <!-- DEPENDENCIES --> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </dependency> </dependencies> <!-- BUILD --> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <!-- REPOSITORIES --> <repositories> <repository> <id>spring-releases</id> <name>Spring Releases</name> <url>https://repo.spring.io/libs-release</url> </repository> <repository> <id>org.jboss.repository.releases</id> <name>JBoss Maven Release Repository</name> <url>https://repository.jboss.org/nexus/content/repositories/releases</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-releases</id> <name>Spring Releases</name> <url>https://repo.spring.io/libs-release</url> </pluginRepository> </pluginRepositories> </project> 

    Entities

     @Entity @Table(name = "\"user\"") public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "user_id") private Integer userID; private String name; public User() {} public User(String name) { this.name = name; } public Integer getUserID() { return userID; } public void setUserID(Integer userID) { this.userID = userID; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("User [userID="); builder.append(userID); builder.append(", name="); builder.append(name); builder.append("]"); return builder.toString(); } } @Entity @Table(name = "room") public class Room { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "room_id") private Integer roomID; private String name; @OneToOne @JoinColumn(name = "user_id", nullable = false) private User owner; public Room() {} public Room(String name, User owner) { super(); this.name = name; this.owner = owner; } public Integer getRoomID() { return roomID; } public void setRoomID(Integer roomID) { this.roomID = roomID; } public String getName() { return name; } public void setName(String name) { this.name = name; } public User getOwner() { return owner; } public void setOwner(User owner) { this.owner = owner; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("Room [roomID="); builder.append(roomID); builder.append(", name="); builder.append(name); builder.append(", owner="); builder.append(owner); builder.append("]"); return builder.toString(); } } @Entity @Table(name = "message") public class Message { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "message_id") private Integer messageID; private String text; @Column(name = "creation_date") @Temporal(TemporalType.TIMESTAMP) private Date creationDate = new Date(); @ManyToOne @JoinColumn(name = "user_id", nullable = false) private User author; @ManyToOne @JoinColumn(name = "room_id", nullable = false) private Room thread; public Message() {} public Message(String text, User author, Room thread) { this.text = text; this.author = author; this.thread = thread; } public Integer getMessageID() { return messageID; } public void setMessageID(Integer messageID) { this.messageID = messageID; } public String getText() { return text; } public void setText(String text) { this.text = text; } public Date getCreationDate() { return creationDate; } public void setCreationDate(Date creationDate) { this.creationDate = creationDate; } public User getAuthor() { return author; } public void setAuthor(User author) { this.author = author; } public Room getThread() { return thread; } public void setThread(Room thread) { this.thread = thread; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("Message [messageID="); builder.append(messageID); builder.append(", text="); builder.append(text); builder.append(", creationDate="); builder.append(creationDate); builder.append(", author="); builder.append(author); builder.append(", thread="); builder.append(thread); builder.append("]"); return builder.toString(); } } @Entity @Table(name = "presence") public class Presence { // это composite key (составной ключ), который состоит // из 2-х ID - пользователя и комнаты @EmbeddedId private PresenceKey id; @Temporal(TemporalType.TIMESTAMP) private Date loggedTime = new Date(); @OneToOne @JoinColumn(name = "user_id", insertable = false, updatable = false) private User user; @OneToOne @JoinColumn(name = "room_id", insertable = false, updatable = false) private Room room; public Presence() {} public Presence(PresenceKey id) { this.id = id; } public PresenceKey getId() { return id; } public void setId(PresenceKey id) { this.id = id; } public Date getLoggedTime() { return loggedTime; } public void setLoggedTime(Date loggedTime) { this.loggedTime = loggedTime; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } public Room getRoom() { return room; } public void setRoom(Room room) { this.room = room; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("Presence [id="); builder.append(id); builder.append(", loggedTime="); builder.append(loggedTime); builder.append(", user="); builder.append(user); builder.append(", room="); builder.append(room); builder.append("]"); return builder.toString(); } } @Embeddable public class PresenceKey implements Serializable { private static final long serialVersionUID = 1L; @Column(name = "room_id") private Integer roomID; @Column(name = "user_id") private Integer userID; public PresenceKey() {} public PresenceKey(User user, Room room) { this.userID = user.getUserID(); this.roomID = room.getRoomID(); } public Integer getRoomID() { return roomID; } public void setRoomID(Integer roomID) { this.roomID = roomID; } public Integer getUserID() { return userID; } public void setUserID(Integer userID) { this.userID = userID; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("PresenceKey [roomID="); builder.append(roomID); builder.append(", userID="); builder.append(userID); builder.append("]"); return builder.toString(); } } 

    Repositories

     public interface UserRepository extends CrudRepository<User, Integer> { User findByName(String name); } public interface RoomRepository extends CrudRepository<Room, Integer> { Room findByName(String name); } public interface MessageRepository extends CrudRepository<Message, Integer> { @Query("select m from Message m where room_id = ?1") List<Message> findAllByRoomID(Integer roomID); } public interface PresenceRepository extends CrudRepository<Presence, Integer> { @Query("select p from Presence p where room_id = ?1") List<Presence> findAllByRoomID(Integer roomID); } 

    application

     @SpringBootApplication public class Application { private static final Logger log = LoggerFactory.getLogger(Application.class); public static void main(String[] args) { SpringApplication.run(Application.class); } @Bean public CommandLineRunner demo(UserRepository userRepo, RoomRepository roomRepo, PresenceRepository presenceRepo, MessageRepository messageRepo) { return (args) -> { userRepo.save(new User("Philip J. Fry")); userRepo.save(new User("Bart Simpson")); userRepo.save(new User("Samurai Jack")); log.info("Смотрим какие пользователи у нас имеются:"); log.info("-------------------------------"); for ( User user : userRepo.findAll() ) { log.info(user.toString()); } log.info(""); log.info("Создаем чат:"); log.info("-------------------------------"); roomRepo.save(new Room("Talks", userRepo.findByName("Bart Simpson"))); for ( Room room : roomRepo.findAll() ) { log.info(room.toString()); } log.info(""); log.info("Добавляем в чат пользователей:"); log.info("-------------------------------"); presenceRepo.save(new Presence( new PresenceKey(userRepo.findByName("Bart Simpson"), roomRepo.findByName("Talks")))); presenceRepo.save(new Presence( new PresenceKey(userRepo.findByName("Samurai Jack"), roomRepo.findByName("Talks")))); log.info(""); log.info("Смотрим кто у нас сидит в чате:"); log.info("-------------------------------"); for ( Presence presence : presenceRepo.findAllByRoomID(roomRepo.findByName("Talks").getRoomID()) ) { log.info(userRepo.findOne(presence.getUser().getUserID()).toString()); } log.info(""); log.info("Общаемся:"); log.info("-------------------------------"); messageRepo.save(new Message("Всем привееееет! Ололо!", userRepo.findByName("Bart Simpson"), roomRepo.findByName("Talks"))); messageRepo.save(new Message("Гитлер капут!", userRepo.findByName("Samurai Jack"), roomRepo.findByName("Talks"))); log.info(""); log.info("Смотрим кто кто отписался в чат:"); log.info("-------------------------------"); for ( Message message : messageRepo.findAllByRoomID(roomRepo.findByName("Talks").getRoomID()) ) { log.info(message.getAuthor().getName() + " пишет: " + message.getText()); } log.info(""); }; } } 

    Conclusion

     example.Application : Смотрим какие пользователи у нас имеются: example.Application : ------------------------------- example.Application : User [userID=1, name=Philip J. Fry] example.Application : User [userID=2, name=Bart Simpson] example.Application : User [userID=3, name=Samurai Jack] example.Application : example.Application : Создаем чат: example.Application : ------------------------------- example.Application : Room [roomID=1, name=Talks, owner=User [userID=2, name=Bart Simpson]] example.Application : example.Application : Добавляем в чат пользователей: example.Application : ------------------------------- example.Application : example.Application : Смотрим кто у нас сидит в чате: example.Application : ------------------------------- example.Application : User [userID=2, name=Bart Simpson] example.Application : User [userID=3, name=Samurai Jack] example.Application : example.Application : Общаемся: example.Application : ------------------------------- example.Application : example.Application : Смотрим кто кто отписался в чат: example.Application : ------------------------------- example.Application : Bart Simpson пишет: Всем привееееет! Ололо! example.Application : Samurai Jack пишет: Гитлер капут! 
    • Great!) Can you tell me why you used GrudRepositories instead of Jpa ?? By the way, why is room and user connected to One-To-One ?? PS fill the project on git plis - Samuliak
    • one
      Use abstractions that provide the methods necessary for your business logic. I did not use pagination and sorting, so the CrudRepository enough. The same with connections - there’s no need to do those that you don’t use. Link to git added. - enzo
    • Thank you!) Helped! I will now understand and edit the project - Samuliak