当前位置: 首页 > 知识库问答 >
问题:

使用嵌入式模型的Spring Boot Hibernate ManyToMany关系

储承
2023-03-14
   package org.sayar.layout.domain;

    import java.util.HashSet;
    import java.util.Set;

    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.JoinColumn;




    import javax.persistence.JoinTable;
    import javax.persistence.ManyToMany;
    import javax.persistence.OneToMany;
    import javax.persistence.Table;

    import org.hibernate.annotations.Nationalized;
    import org.sayar.layout.base.general.domain.GeneralDomain;
    import org.sayar.layout.constants.SchemaList;
    import org.sayar.layout.domain.uaa.Role;
    import org.sayar.layout.domain.uaa.RoleGroup;
    import org.springframework.data.annotation.Transient;

    import com.fasterxml.jackson.annotation.JsonInclude;
    import com.fasterxml.jackson.annotation.JsonManagedReference;

    import lombok.AllArgsConstructor;
    import lombok.Getter;
    import lombok.NoArgsConstructor;
    import lombok.Setter;

    /**
     * This domain for store and transfer Menu
     *
     * @author Ehsan
     */
    @Setter
    @Getter
    @AllArgsConstructor
    @NoArgsConstructor
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @Entity(name = Menu.TABLE_NAME)
    @Table(name = Menu.TABLE_NAME, schema = SchemaList.LAYOUT)
    public class Menu extends GeneralDomain {
        @Transient
        public final static String TABLE_NAME = "Menu";


        public class CN {
            public final static String title = "title";
            public final static String description = "description";
            public final static String banner = "banner";
        }

        @Nationalized
        @Column(name = CN.title, length = 128, nullable = false)
        private String title;

        @Nationalized
        @Column(name = CN.description, length = 1000)
        private String description;

        @Nationalized
        @Column(name = CN.banner, length = 128)
        private String banner;

        /* Relationships */

        @ManyToMany(fetch = FetchType.EAGER)
        @JoinTable(name = "Menu_RoleGroup",
                schema = SchemaList.LAYOUT,
                joinColumns = @JoinColumn(name = "menuId", referencedColumnName = GCN.id), //
                inverseJoinColumns = @JoinColumn(name = "roleGroupId", referencedColumnName = GCN.id))
        private Set<RoleGroup> roleGroupSet;

        @OneToMany(mappedBy = MenuItem.CN.menu, fetch = FetchType.EAGER)
        @JsonManagedReference
        private Set<MenuItem> menuItemSet = new HashSet<>();

        /* Constructors */
        public Menu(String title, String banner, String description) {
            this.title = title;
            this.banner = banner;
            this.description = description;
        }

        public Menu(String title, String banner, String description, Set<RoleGroup> roleGroupSet) {
            this.title = title;
            this.banner = banner;
            this.description = description;
            this.roleGroupSet = roleGroupSet;
        }

        public Menu(String id) {
            super(id);
        }
        /* Other classes or enumerations */

    }
    .
    .
    .
    .
    .

    package org.sayar.layout.domain.uaa;

    import java.util.Date;

    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.EnumType;
    import javax.persistence.Enumerated;
    import javax.persistence.Table;

    import org.hibernate.annotations.Nationalized;
    import org.sayar.layout.base.general.domain.GeneralDomain;
    import org.sayar.layout.constants.SchemaList;
    import org.springframework.data.annotation.Transient;

    import com.fasterxml.jackson.annotation.JsonInclude;

    import lombok.AllArgsConstructor;
    import lombok.Getter;
    import lombok.NoArgsConstructor;
    import lombok.Setter;

    /**
     * This domain for store and transfer RoleGroup
     *
     * @author Ehsan
     *
     */
    @Setter
    @Getter
    @AllArgsConstructor
    @NoArgsConstructor
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @Entity(name = RoleGroup.TABLE_NAME)
    @Table(name = RoleGroup.TABLE_NAME, schema = SchemaList.UAA)
    public class RoleGroup extends GeneralDomain {
        @Transient
        public final static String TABLE_NAME = "RoleGroup";

        public class CN {
            public final static String title = "title";
            public final static String status = "status";
        }

        @Nationalized
        @Column(name = CN.title, length = 128, nullable = false)
        private String title;

        @Enumerated(EnumType.STRING)
        @Column(name = CN.status, nullable = false)
        private Status status;

        public RoleGroup(String id) {
            super(id);
        }

        /* Relationships */
        /* Constructors */
        /* Other classes or enumerations */
        public enum Status {
            ACTIVE, DE_ACTIVE
        }
    }
    .
    .
    .
    package org.sayar.layout.service.menu;

    import org.sayar.layout.base.util.Print;
    import org.sayar.layout.domain.Menu;
    import org.sayar.layout.repository.megaitem.MegaItemRepository;
    import org.sayar.layout.repository.menu.MenuRepository;
    import org.sayar.layout.repository.menuitem.MenuItemRepository;
    import org.sayar.layout.rest.menu.dto.*;
    import org.springframework.stereotype.Service;
    import org.sayar.layout.dao.menu.MenuDaoImpl;
    import org.springframework.data.domain.Page;
    import org.springframework.data.domain.Pageable;
    import org.springframework.http.ResponseEntity;

    import java.util.List;

    import lombok.RequiredArgsConstructor;
    import org.springframework.transaction.annotation.Transactional;
    import reactor.core.publisher.Mono;

    /**
     * Spring service implementation for the Menu entity.
     *
     * @author Ehsan
     */
    @Service
    @RequiredArgsConstructor
    public class MenuServiceImpl implements MenuService {

        private final MenuDaoImpl entityDao;
        private final MenuRepository entityRepository;
        private final MenuItemRepository menuItemRepository;
        private final MegaItemRepository megaItemRepository;

        @Override
        public Mono<ResponseEntity<Boolean>> create(ReqMenuCreateDTO entity, String userId) {
            return Mono.just(entityRepository.save(entity.map(userId)))
                    .flatMap(createdEntity -> Mono.just(ResponseEntity.ok().body(true))
                    )
                    .defaultIfEmpty(ResponseEntity.ok().body(false));
        }

        @Transactional
        @Override
        public Mono<ResponseEntity<Boolean>> update(String id, ReqMenuUpdateDTO entity) {

            Mono.just(entityRepository.update(id, entity.getTitle(), entity.getBanner(), entity.getDescription())).subscribe();
            Mono.just(entityRepository.deleteRoleMenu(id)).subscribe();
            Print.print("title", entity);

            if (entity.getRoleGroupIdSet() != null && !entity.getRoleGroupIdSet().isEmpty())
                for (String roleId : entity.getRoleGroupIdSet()) {
                    Mono.just(entityRepository.updateRoleMenu(id, roleId)).subscribe();
                }
            return Mono.just(ResponseEntity.ok().body(true));

        }
    .
    .
    .
    .
    .
    package org.sayar.layout.repository.menu;


    import org.sayar.layout.constants.SchemaList;
    import org.sayar.layout.repository.menu.dto.ResRoleGetListRepoDTO;
    import org.sayar.layout.rest.menu.dto.ResMenuGetListDTO;
    import org.sayar.layout.repository.menu.dto.ResMenuGetOneRepoDTO;
    import org.sayar.layout.rest.menu.dto.ResMenuGetOneDTO;
    import org.sayar.layout.rest.menu.dto.ResMenuGetPageDTO;
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.stereotype.Repository;

    import java.util.List;
    import java.util.Optional;

    import org.sayar.layout.domain.Menu;
    import org.springframework.data.domain.Page;
    import org.springframework.data.domain.Pageable;
    import org.springframework.data.jpa.repository.Modifying;
    import org.springframework.data.jpa.repository.Query;
    import org.springframework.data.repository.query.Param;
    import org.springframework.transaction.annotation.Transactional;

    /**
     * Spring Data SQL Server repository for the Menu entity.
     *
     * @author Ehsan
     */
    @Repository
    public interface MenuRepository extends JpaRepository<Menu, String> {

        //  UPDATE ALL STARTS HERE
        @Transactional
        @Modifying
        @Query(value = "UPDATE Menu AS m SET m.title = :title , m.description = :description, m.banner = :banner WHERE m.id = :id")
        Integer update(@Param("id") String id, @Param("title") String title, @Param("description") String description, @Param("banner") String banner);

        @Transactional
        @Modifying
        @Query(value = "DELETE FROM layout.Menu_RoleGroup WHERE menuId = :id", nativeQuery = true)
        Integer deleteRoleMenu(@Param("id") String id);

        @Transactional
        @Modifying
        @Query(value = "INSERT INTO layout.Menu_RoleGroup (menuId,roleGroupId) VALUES (:menuId,:roleGroupId)", nativeQuery = true)
        Integer updateRoleMenu(@Param("menuId") String menuId, @Param("roleGroupId") String roleGroupId);
    }

共有1个答案

柯正谊
2023-03-14

其实我知道怎么解决它!在这种情况下,我必须创建一个域模型,如MenuRoleGroup作为一个实体,然后添加一个可嵌入的字段,例如MenuRoleGroupEmbeddable,并在MenuRoleGroup中使用create@embeddedId字段。然后在MenuRoleGroupEmbeddable中添加Menu和RoleGroup的主键。

因此Spring Data能够创建扩展JPA存储库的MenuRoleGroupRepository,但请注意,这个表有两个主键,而不是一个。

注意,MenuRoleGroup中的MenuRoleGroupEmbeddable字段没有关系,但Menu和RoleGroup都与MenuRoleGroupEmbeddable模型有@ManyToOne关系。

下面是一个例子。

package org.sayar.wms.domain.Menu;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.GenericGenerator;
import org.sayar.wms.base.general.domain.GeneralDomain;
import org.sayar.wms.constants.SchemaList;
import org.sayar.wms.domain.container.Container;
import org.sayar.wms.domain.product.ProductContainerEmbeddable;
import org.springframework.data.annotation.Transient;

import javax.persistence.*;
import java.util.Date;


@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
@Entity(name = MenuRoleGroup.TABLE_NAME)
@Table(name = MenuRoleGroup.TABLE_NAME, schema = SchemaList.WMS)
public class MenuRoleGroup {

    @Transient
    public final static String TABLE_NAME = "MenuRoleGroup";

    public class CN {
        public final static String startDate = "startDate";
    }

    @EmbeddedId
    private MenuRoleGroupEmbeddable menuRoleGroupEmbeddable;

    @JoinColumn(name = CN.startDate, referencedColumnName = GeneralDomain.GCN.id)
    private Date startDate;

}


package org.sayar.wms.domain.Menu;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.sayar.wms.base.general.domain.GeneralDomain;
import org.sayar.wms.domain.container.Container;

import javax.persistence.CascadeType;
import javax.persistence.Embeddable;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import java.io.Serializable;
import java.util.Set;

/**
 * This domain for store and transfer Warehouse
 *
 * @author masoud
 */
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
@Embeddable
public class ProductContainerEmbeddable implements Serializable {

    public class CN {
        public final static String menuId = "menuId";
        public final static String roleGroupId = "roleGroupId";
    }

    /* Relationships */

    @ManyToOne
    @JoinColumn(name = CN.menu, referencedColumnName = "id")
    private Menu menu;

    @ManyToOne
    @JoinColumn(name = CN.roleGroup, referencedColumnName ="id")
    private RoleGroup roleGroup;

    /* Constructors */


    /* Other classes or enumerations */

}

menuId和roleGroupId都是MenuRoleGroup实体的主键。

 类似资料:
  • 我一直在尝试使用Keras构建一个多输入模型。我来自使用顺序模型,并且只有一个相当直接的输入。我一直在查看StackOverflow上的留档(https://keras.io/getting-started/functional-api-guide/)和一些答案(如何在Keras 2.0中“合并”顺序模型?)。基本上,我想要的是让两个输入训练一个模型。一个输入是一段文本,另一个是从该文本中提取的一

  • 我正在构建一个使用MySQL数据库的Spring3 MVC应用程序,并且最近将Flyway集成到解决方案中以管理数据库迁移。我已成功配置我的应用程序上下文.xml根据 Flyway 文档,以便在应用程序启动时,Flyway 将迁移到最新版本。 我很难让Flyway很好地完成我的单元/功能测试。我正在使用SpringDataJPA作为数据访问层,并构建了一些JUnit测试来测试一些自定义查询。 我在

  • 我需要使用Java运行嵌入高可用性模式的Neo4j。我下载了Neo4j的企业版,并对neo4j.properties文件进行了更改,如neo4j高可用性设置教程中所述。现在,如何使用这个修改过的neo4j.properties文件在高可用性模式下使用Java运行neo4j?

  • 我希望在使用neo4j数据库的应用程序中使用此结构。 在这里,我将在三个不同的服务器上部署我的应用程序,每个服务器都有自己的嵌入式neo4j数据库。 我希望所有数据库都自动同步。 它适合我的大数据应用程序吗? 我正在使用SpringDataNeo4j,如何在SDN中配置此结构。 我需要企业版的neo4j为此。 有没有其他可以使用的框架/技术? 我几乎完成了这样的结构 我的Web应用程序部署在 >

  • 这描述了 _neo4j-embedded_,让你在Python应用中嵌入Neo4j数据库的一个Python库。 从参考文档和这个章节的安装介绍分开,你可以参考:第 9 章 在Python应用中使用Neo4j。 这个工程在GitHub上面的源代码地址: https://github.com/neo4j/python-embedded 19.1. 安装 注意:Neo4j 数据库(来自社区版)本身就被包

  • Ruby, like fire, is a very useful friend, and a very dangerous enemy. — Mikkel Bruun 在模板中使用嵌入式 Ruby 帮助构建动态的配置文件或实现数组遍历是一种强大的方式。 然而,你也可以在配置清单中使用 inline_template 函数直接嵌入 Ruby 而不必使用分离的模板文件。 操作步骤 在 Puppet