繁体   English   中英

Spring-Hibernate Many-to-Many:保存实体,如果数据库中存在则创建关系

[英]Spring-Hibernate Many-to-Many : Save an entity, or create a relationship if it exists in the database

我是 Spring 和 Hibernate 的新手,遇到了几天后无法解决的问题。

在我的项目中,我在服务器和用户实体之间使用多对多关系。 一个用户可以存在于多个服务器上。

我的想法是:服务器 <-> Server_Users <-> 用户

创建表的代码:

CREATE TABLE public.servers (
    id bigint NOT NULL,
    s_snowflake bigint NOT NULL,
    name character varying(64) NOT NULL
);

CREATE TABLE public.users (
    id bigint NOT NULL,
    u_snowflake bigint NOT NULL,
    name character varying(64) NOT NULL
);

CREATE TABLE public.server_users (
    id bigint NOT NULL,
    server_id bigint NOT NULL,
    user_id bigint NOT NULL
);

这就是我的课程的样子:

@Entity
@Table(name = "servers")
public class Server {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(name = "s_snowflake", unique = true)
    private long snowflake;

    private String name;

    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinTable(
            name = "server_users",
            joinColumns = @JoinColumn(name = "server_id"),
            inverseJoinColumns = @JoinColumn(name = "user_id")
    )
    private Set<User> users = new HashSet<>();

}

@Entity
@Table(name = "users")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(name = "u_snowflake", unique = true)
    private long snowflake;

    private String name;

    @ManyToMany(mappedBy = "users", targetEntity = Server.class, fetch = FetchType.EAGER)
    private Set<Server> servers = new HashSet<>();

}

这在我初始化数据时效果很好。 我创建了一个服务器 object 并用用户填充它,一切都正确保存。

但是当我尝试保存包含用户表中已经存在的用户的服务器时遇到问题(如果我从数据库中级联删除服务器,用户不应该被删除)。

有没有办法配置 Hibernate 以便在必要时添加新用户,但如果用户存在,则使用 Server_Users 表将其“创建关系”到新服务器?

我尝试使用 Cascade.SAVE_UPDATE 和其他方式,但没有结果。

瘾:

这是我用来保存和更新的 DAO class 方法:

public abstract class AbstractDAOImpl<T> implements AbstractDAO<T> {
    public void save(T entity) {
        Session session = HibernateSessionFactoryUtil.getSessionFactory().openSession();
        Transaction trx = session.beginTransaction();
        session.save(entity);
        trx.commit();
        session.close();
    }
    public void update(T entity) {
        Session session = HibernateSessionFactoryUtil.getSessionFactory().openSession();
        Transaction trx = session.beginTransaction();
        session.update(entity);
        trx.commit();
        session.close();
    }
}

服务器添加逻辑。 首先,我将它保存到数据库中,然后用用户填充 Set 并执行update()如果包含用户的表为空,则此操作有效,所有必要的记录和连接都在 Server_Users 和 Users 表中创建:

public static void addServer(Guild guild) {

        Server server = new Server(Long.parseLong(guild.getId()), guild.getName());
        serverDAO.save(server);

        for (Member m : guild.getMembers()) {
            User user = new User(Long.parseLong(m.getId()), m.getUser().getName());
            user.addServer(server);
            server.addUser(user);
        }

        serverDAO.update(server);

    }

我找到了解决方案

    @Cascade({
            org.hibernate.annotations.CascadeType.SAVE_UPDATE,
            org.hibernate.annotations.CascadeType.MERGE,
            org.hibernate.annotations.CascadeType.PERSIST
    })
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(
            name = "server_users",
            joinColumns = @JoinColumn(name = "server_sn"),
            inverseJoinColumns = @JoinColumn(name = "user_sn")
    )
    private Set<User> users = new HashSet<>();

我在服务器和用户代码中添加了 CascadeTypes SAVE_UPDATE、MERGE 和 PERSIST

另外,我重新设计了base的架构,把雪花做成Primary Keys,因为值总是唯一的

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM