Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用@MapKey和@ManyToMany关系中的映射(JPA+Hibernate 4.1.9)_Hibernate_Jpa_Map - Fatal编程技术网

使用@MapKey和@ManyToMany关系中的映射(JPA+Hibernate 4.1.9)

使用@MapKey和@ManyToMany关系中的映射(JPA+Hibernate 4.1.9),hibernate,jpa,map,Hibernate,Jpa,Map,我在使用@MapKey注释来映射使用map的@ManyToMany关系时遇到了一个问题,map包含目标实体属性作为映射条目键,目标实体对象本身作为映射条目值 不带PK、FK和唯一约束的数据库架构为: 申请表: CREATE TABLE "APM_APPLICATION" ( "ID_APPLICATION" BIGINT NOT NULL, "NAME" VARCHAR(64) NOT NULL, "DESCRIPTION" VARCHAR(1024)); CREATE

我在使用@MapKey注释来映射使用map的@ManyToMany关系时遇到了一个问题,map包含目标实体属性作为映射条目键,目标实体对象本身作为映射条目值

不带PK、FK和唯一约束的数据库架构为: 申请表:

CREATE TABLE "APM_APPLICATION" (
    "ID_APPLICATION" BIGINT NOT NULL,
    "NAME" VARCHAR(64) NOT NULL,
    "DESCRIPTION" VARCHAR(1024));
CREATE TABLE "APM_FUNCTION" (
    "ID_FUNCTION" BIGINT NOT NULL,
    "ID_APPLICATION" BIGINT NOT NULL,
    "NAME" VARCHAR(64) NOT NULL,
    "DESCRIPTION" VARCHAR(1024));
功能表:

CREATE TABLE "APM_APPLICATION" (
    "ID_APPLICATION" BIGINT NOT NULL,
    "NAME" VARCHAR(64) NOT NULL,
    "DESCRIPTION" VARCHAR(1024));
CREATE TABLE "APM_FUNCTION" (
    "ID_FUNCTION" BIGINT NOT NULL,
    "ID_APPLICATION" BIGINT NOT NULL,
    "NAME" VARCHAR(64) NOT NULL,
    "DESCRIPTION" VARCHAR(1024));
参数表:

CREATE TABLE "APM_PARAM" (
    "ID_PARAM" BIGINT NOT NULL,
    "ID_APPLICATION" BIGINT NOT NULL,
    "NAME" VARCHAR(64) NOT NULL,
    "DESCRIPTION" VARCHAR(1024),
    "VALUE" VARCHAR(64));
具有复合主键的函数和参数联接表:

CREATE TABLE "APM_FUNCTION_PARAM" (
    "ID_FUNCTION" BIGINT NOT NULL,
    "ID_PARAM" BIGINT NOT NULL);
没有构造函数、getter、setter和JPA id生成设置的域模型是: 应用实体:

@Entity
@Table(name = "APM_APPLICATION")
public class Application {

@Id
@Column(name = "ID_APPLICATION")
private Long id;

@Column(name = "NAME")
private String name;

@Column(name = "DESCRIPTION")
private String description;

@OneToMany(mappedBy = "application")
@MapKey(name = "name")
private Map<String, Parameter> parameters = new HashMap<String, Parameter>();

@OneToMany(mappedBy = "application")
@MapKey(name = "name")
private Map<String, Function> functions = new HashMap<String, Function>();

// constructors, getters and setters omitted

public String toString() {
    return "Application[id='" + id +"', " +
            "name='" + name + "', " +
            "parametersCount='" +parameters.size() + "', " +
            "functionsCount='" + functions.size() + "']";
}
@Entity
@Table(name = "APM_FUNCTION")
public class Function {

@Id
@Column(name = "ID_FUNCTION")
private Long id;

@ManyToOne
@JoinColumn(name = "ID_APPLICATION")
private Application application;

@Column(name = "NAME")
private String name;

@Column(name = "DESCRIPTION")
private String description;

@ManyToMany
@JoinTable(name = "APM_FUNCTION_PARAM",
        joinColumns = @JoinColumn(name = "ID_FUNCTION"),
        inverseJoinColumns = @JoinColumn(name = "ID_PARAM"))
@MapKey(name = "name")
private Map<String, Parameter> parameters = new HashMap<String, Parameter>();

// constructors, getters and setters omitted

public String toString() {
    return "Function[id='" + id + "', " +
            "application='" + application + "', " +
            "name='" + name +"', " +
            "parametersCount='" + parameters.size() + "']";
}
看起来Hibernate正在试图在映射本身中查找@MapKey注释中指定名称的属性,而不是目标实体

是否可以使用带有目标实体属性的映射作为多个关系中的键?我怎样才能做到呢


谢谢您的时间。

您能发布toString方法吗?我已尝试复制此问题,但没有收到相同的错误。testApplicationInfo工作正常。我在表格中输入了一些数据,得到如下结果:。。。函数:Function:Function{id=1,name='Function1',description=,parameters={Parameter1=Parameter{id=1,name='Parameter1',value='ParamValue1'},Parameter2=Parameter{id=2,name='Parameter2',value='ParamValue2'}}…当然,刚才在实体代码中添加了toString方法。我认为问题出在toString方法中。我使用IntelliJ生成了一个默认实现,没有问题。我使用了您的toString实现,我也无法复制它。您能检查一下APM_PARAM表中是否有NAME列吗?
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
    <persistence-unit name="apmPersistenceUnit" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.DerbyTenSevenDialect"/>
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.globally_quoted_identifiers" value="true"/>
        </properties>
    </persistence-unit>
</persistence>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:context="http://www.springframework.org/schema/context"
   xsi:schemaLocation=" http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context.xsd">
    <import resource="spring-jpa.xml" />
    <context:property-placeholder location="META-INF/configuration.properties" />
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${apm.db.driverClassName}"/>
        <property name="url" value="${apm.db.url}"/>
        <property name="initialSize" value="${apm.db.connPoolInitialSize}"/>
        <property name="maxActive" value="${apm.db.connPoolMaxActive}"/>
    </bean>
</beans>
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
   xmlns:jpa="http://www.springframework.org/schema/data/jpa"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
    <jpa:repositories base-package="cz.syntea.apm.repository" />
    <bean id="entityManagerFactory"
      class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
      depends-on="dbCreator">
        <property name="dataSource" ref="dataSource"/>
        <property name="jpaDialect">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
        </property>
    </bean>
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>
    <tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
</beans>
@Test
@Transactional
public void testApplicationInfo() {
    List<Application> apps = appService.getApplications();
    for (Application app : apps) {
        System.out.println("Application: " + app);
        System.out.println("Parameters:" );
        for (Parameter p : app.getParameters().values()) {
            System.out.println("Parameter: " + p);
        }
        System.out.println("Functions:");
        for (Function f : app.getFunctions().values()) {
            System.out.println("Function: " + f); // exception is thrown in toString method, that tries to access parameters map
            for (Parameter p : f.getParameters().values()) {
                System.out.println("Parameter: " + p);
            }
        }
    }
}
Hibernate: select applicatio0_."ID_APPLICATION" as ID1_6_, applicatio0_."DESCRIPTION" as DESCRIPT2_6_, applicatio0_."NAME" as NAME3_6_ from "APM_APPLICATION" applicatio0_
Hibernate: select parameters0_.ID_APPLICATION as ID5_6_2_, parameters0_."ID_PARAM" as ID1_5_2_, parameters0_."NAME" as formula3_2_, parameters0_."ID_PARAM" as ID1_5_1_, parameters0_.ID_APPLICATION as ID5_5_1_, parameters0_."NAME" as NAME2_5_1_, parameters0_."RELATION" as RELATION3_5_1_, parameters0_."DATA_TYPE" as DATA4_5_1_, parameters0_.ID_VALUE as ID6_5_1_, value1_."ID_VALUE" as ID1_1_0_, value1_."BOOLEAN_SET" as BOOLEAN2_1_0_, value1_."DOUBLE_VALUE" as DOUBLE3_1_0_, value1_."INTEGER_VALUE" as INTEGER4_1_0_ from "APM_PARAM" parameters0_ left outer join "APM_VALUE" value1_ on parameters0_.ID_VALUE=value1_."ID_VALUE" where parameters0_.ID_APPLICATION=?
Hibernate: select functions0_.ID_APPLICATION as ID4_6_1_, functions0_."ID_FUNCTION" as ID1_7_1_, functions0_."NAME" as formula2_1_, functions0_."ID_FUNCTION" as ID1_7_0_, functions0_.ID_APPLICATION as ID4_7_0_, functions0_."DESCRIPTION" as DESCRIPT2_7_0_, functions0_."NAME" as NAME3_7_0_ from "APM_FUNCTION" functions0_ where functions0_.ID_APPLICATION=?
Application: Application[id='25050', name='TST_APP_1', parametersCount='2', functionsCount='2']
Parameters:
Hibernate: select functions0_.ID_PARAM as ID2_5_2_, functions0_.ID_FUNCTION as ID1_11_2_, function1_."ID_FUNCTION" as ID1_7_0_, function1_.ID_APPLICATION as ID4_7_0_, function1_."DESCRIPTION" as DESCRIPT2_7_0_, function1_."NAME" as NAME3_7_0_, applicatio2_."ID_APPLICATION" as ID1_6_1_, applicatio2_."DESCRIPTION" as DESCRIPT2_6_1_, applicatio2_."NAME" as NAME3_6_1_ from "APM_FUNCTION_PARAM" functions0_ inner join "APM_FUNCTION" function1_ on functions0_.ID_FUNCTION=function1_."ID_FUNCTION" left outer join "APM_APPLICATION" applicatio2_ on function1_.ID_APPLICATION=applicatio2_."ID_APPLICATION" where functions0_.ID_PARAM=?
Parameter: Parameter[id='25051', application='Application[id='25050', name='TST_APP_1', parametersCount='2', functionsCount='2']', name='b', value='20', functionsCount='1']
Hibernate: select functions0_.ID_PARAM as ID2_5_2_, functions0_.ID_FUNCTION as ID1_11_2_, function1_."ID_FUNCTION" as ID1_7_0_, function1_.ID_APPLICATION as ID4_7_0_, function1_."DESCRIPTION" as DESCRIPT2_7_0_, function1_."NAME" as NAME3_7_0_, applicatio2_."ID_APPLICATION" as ID1_6_1_, applicatio2_."DESCRIPTION" as DESCRIPT2_6_1_, applicatio2_."NAME" as NAME3_6_1_ from "APM_FUNCTION_PARAM" functions0_ inner join "APM_FUNCTION" function1_ on functions0_.ID_FUNCTION=function1_."ID_FUNCTION" left outer join "APM_APPLICATION" applicatio2_ on function1_.ID_APPLICATION=applicatio2_."ID_APPLICATION" where functions0_.ID_PARAM=?
Parameter: Parameter[id='25050', application='Application[id='25050', name='TST_APP_1', parametersCount='2', functionsCount='2']', name='a', value='100', functionsCount='2']
Functions:
SQL Error: 20000, SQLState: 42X04
Column 'A5.PARAMETERS0_.NAME' is either not in any table in the FROM list or appears within a join specification and is outside the scope of the join specification or appears in a HAVING clause and is not in the GROUP BY list. If this is a CREATE or ALTER TABLE  statement then 'A5.PARAMETERS0_.NAME' is not a column in the target table.