如何使用 Maven 多模块处理循环引用 +多对多 jpa

发布于 2025-01-09 13:01:01 字数 11011 浏览 1 评论 0原文

我一直在尝试将我的 API 分离到一个多模块 springboot 应用程序中,但我一直在两个应该位于不同模块中的不同实体之间的多对多关系上陷入循环引用。

首先我们有模块 virtual-mattress-spreadsheet 内的实体电子表格:

@Entity
data class Spreadsheet(
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Long? = null,
    val title: String,
    @ManyToMany(fetch = FetchType.EAGER)
    val userList: List<User>
)

它是 pom.xml:

    <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.virtual-mattress</groupId>
        <artifactId>virtual-mattress</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <groupId>com.virtual-mattress</groupId>
    <artifactId>virtual-mattress-spreadsheet</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>virtual-mattress-sheet</name>
    <description>Virtual Mattress sheet module</description>
    <properties>
        <java.version>11</java.version>
        <kotlin.version>1.6.10</kotlin.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.virtual-mattress</groupId>
            <artifactId>virtual-mattress-user</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web-services</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-kotlin</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-reflect</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-stdlib-jdk8</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
        <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.jetbrains.kotlin</groupId>
                <artifactId>kotlin-maven-plugin</artifactId>
                <configuration>
                    <args>
                        <arg>-Xjsr305=strict</arg>
                    </args>
                    <compilerPlugins>
                        <plugin>spring</plugin>
                        <plugin>jpa</plugin>
                    </compilerPlugins>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.jetbrains.kotlin</groupId>
                        <artifactId>kotlin-maven-allopen</artifactId>
                        <version>${kotlin.version}</version>
                    </dependency>
                    <dependency>
                        <groupId>org.jetbrains.kotlin</groupId>
                        <artifactId>kotlin-maven-noarg</artifactId>
                        <version>${kotlin.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>

</project>

然后我们在模块 virtual-mattress-user 内有实体用户:

    @Entity
data class User(
    val id: Long?,
    val name: String,
    val email: String,

    @Enumerated(EnumType.STRING)
    val type: UserType,
    val password: String,
    
    @ManyToMany
    val sheetList: List<Sheet>
)

它是 pom.xml:

    <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.virtual-mattress</groupId>
        <artifactId>virtual-mattress</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <groupId>com.virtual-mattress</groupId>
    <artifactId>virtual-mattress-user</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>virtual-mattress-user</name>
    <description>Virtual Mattress user module</description>
    <properties>
        <java.version>11</java.version>
        <kotlin.version>1.6.10</kotlin.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.virtual-mattress</groupId>
            <artifactId>virtual-mattress-spreadsheet</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web-services</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-kotlin</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-reflect</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-stdlib-jdk8</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
        <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.jetbrains.kotlin</groupId>
                <artifactId>kotlin-maven-plugin</artifactId>
                <configuration>
                    <args>
                        <arg>-Xjsr305=strict</arg>
                    </args>
                    <compilerPlugins>
                        <plugin>spring</plugin>
                        <plugin>jpa</plugin>
                    </compilerPlugins>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.jetbrains.kotlin</groupId>
                        <artifactId>kotlin-maven-allopen</artifactId>
                        <version>${kotlin.version}</version>
                    </dependency>
                    <dependency>
                        <groupId>org.jetbrains.kotlin</groupId>
                        <artifactId>kotlin-maven-noarg</artifactId>
                        <version>${kotlin.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>

</project>

问题是,当我尝试构建项目时,我收到以下错误:

org.apache.maven.ProjectCycleException: The projects in the reactor contain a cyclic reference: Edge between 'Vertex{label='com.virtual-mattress:virtual-mattress-user:0.0.1-SNAPSHOT'}' and 'Vertex{label='com.virtual-mattress:virtual-mattress-spreadsheet:0.0.1-SNAPSHOT'}' introduces to cycle in the graph com.virtual-mattress:virtual-mattress-spreadsheet:0.0.1-SNAPSHOT --> com.virtual-mattress:virtual-mattress-user:0.0.1-SNAPSHOT --> com.virtual-mattress:virtual-mattress-sheet:0.0.1-SNAPSHOT

这就是我已经走了多远。我不知道如何处理它,因为两个实体位于不同的同级模块中,并且我需要在它们两个中导入另一个实体。

我什至考虑将我的模型移动到一个单独的通用模块,这样我就可以毫无问题地将其导入到两个模块中,但这似乎是一种解决方法,可能有更好的解决方案。

希望你能帮助我。

提前致谢。

I've been trying to separate the my API into a multi module springboot application but I've got stuck with cyclic references on a many to many relation that I have between two different entities that are supposed to be in different modules.

first we have the entity Spreadsheet that's inside the module virtual-mattress-spreadsheet:

@Entity
data class Spreadsheet(
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Long? = null,
    val title: String,
    @ManyToMany(fetch = FetchType.EAGER)
    val userList: List<User>
)

And it's pom.xml:

    <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.virtual-mattress</groupId>
        <artifactId>virtual-mattress</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <groupId>com.virtual-mattress</groupId>
    <artifactId>virtual-mattress-spreadsheet</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>virtual-mattress-sheet</name>
    <description>Virtual Mattress sheet module</description>
    <properties>
        <java.version>11</java.version>
        <kotlin.version>1.6.10</kotlin.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.virtual-mattress</groupId>
            <artifactId>virtual-mattress-user</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web-services</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-kotlin</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-reflect</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-stdlib-jdk8</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
        <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.jetbrains.kotlin</groupId>
                <artifactId>kotlin-maven-plugin</artifactId>
                <configuration>
                    <args>
                        <arg>-Xjsr305=strict</arg>
                    </args>
                    <compilerPlugins>
                        <plugin>spring</plugin>
                        <plugin>jpa</plugin>
                    </compilerPlugins>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.jetbrains.kotlin</groupId>
                        <artifactId>kotlin-maven-allopen</artifactId>
                        <version>${kotlin.version}</version>
                    </dependency>
                    <dependency>
                        <groupId>org.jetbrains.kotlin</groupId>
                        <artifactId>kotlin-maven-noarg</artifactId>
                        <version>${kotlin.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>

</project>

Then we have the entity user inside the module virtual-mattress-user:

    @Entity
data class User(
    val id: Long?,
    val name: String,
    val email: String,

    @Enumerated(EnumType.STRING)
    val type: UserType,
    val password: String,
    
    @ManyToMany
    val sheetList: List<Sheet>
)

and it's pom.xml:

    <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.virtual-mattress</groupId>
        <artifactId>virtual-mattress</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <groupId>com.virtual-mattress</groupId>
    <artifactId>virtual-mattress-user</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>virtual-mattress-user</name>
    <description>Virtual Mattress user module</description>
    <properties>
        <java.version>11</java.version>
        <kotlin.version>1.6.10</kotlin.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.virtual-mattress</groupId>
            <artifactId>virtual-mattress-spreadsheet</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web-services</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-kotlin</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-reflect</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-stdlib-jdk8</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
        <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.jetbrains.kotlin</groupId>
                <artifactId>kotlin-maven-plugin</artifactId>
                <configuration>
                    <args>
                        <arg>-Xjsr305=strict</arg>
                    </args>
                    <compilerPlugins>
                        <plugin>spring</plugin>
                        <plugin>jpa</plugin>
                    </compilerPlugins>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.jetbrains.kotlin</groupId>
                        <artifactId>kotlin-maven-allopen</artifactId>
                        <version>${kotlin.version}</version>
                    </dependency>
                    <dependency>
                        <groupId>org.jetbrains.kotlin</groupId>
                        <artifactId>kotlin-maven-noarg</artifactId>
                        <version>${kotlin.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>

</project>

The problem is that when i try to build the project I get the following error:

org.apache.maven.ProjectCycleException: The projects in the reactor contain a cyclic reference: Edge between 'Vertex{label='com.virtual-mattress:virtual-mattress-user:0.0.1-SNAPSHOT'}' and 'Vertex{label='com.virtual-mattress:virtual-mattress-spreadsheet:0.0.1-SNAPSHOT'}' introduces to cycle in the graph com.virtual-mattress:virtual-mattress-spreadsheet:0.0.1-SNAPSHOT --> com.virtual-mattress:virtual-mattress-user:0.0.1-SNAPSHOT --> com.virtual-mattress:virtual-mattress-sheet:0.0.1-SNAPSHOT

And this is how far I've got. I don't know how to handle it since both entities are in different sibling modules and I need to import the other entity in both of them.

I even considered to move my models to a separate common module so I can import it in both with no problems but this seems to much as a work around, there may be a better solution for this.

Hope you are able to help me.

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文