Hibernate 休眠@manytone和@OneToMany以列表形式获取数据(记录数)

Hibernate 休眠@manytone和@OneToMany以列表形式获取数据(记录数),hibernate,spring-mvc,hibernate-mapping,entity-relationship,hbmxml,Hibernate,Spring Mvc,Hibernate Mapping,Entity Relationship,Hbmxml,我有两张桌子 1.Org[Org\u ID,PARENT\u ID,LANG\u ID(参考LANG)] 2.语言[语言ID,语言名称] 我的JAVA实体文件 Lang.java @Entity @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "langId") @JsonIgnoreProperties({ "hibernateLazyInitializer", "hand

我有两张桌子
1.Org[Org\u ID,PARENT\u ID,LANG\u ID(参考LANG)] 2.语言[语言ID,语言名称]

  • 我的JAVA实体文件

    Lang.java

    @Entity
    @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "langId")
    @JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" })
    @SuppressWarnings("serial")
    public class Lang implements java.io.Serializable {
        private BigDecimal langId;
        private String langName;
        private Set<Org> orgs = new HashSet<Org>(0);
        public Lang() {
        }
        public Lang(BigDecimal langId, Set<Org> orgs) {
            this.langId = langId;
            this.orgs = orgs;
        }
        public BigDecimal getLangId() {
            return this.langId;
        }
        public void setLangId(BigDecimal langId) {
            this.langId = langId;
        }
        public String getLangName() {
            return this.langName;
        }
        public void setLangName(String langName) {
            this.langName = langName;
        }public void setOrgs(Set<Org> orgs) {
            this.orgs = orgs;
        }
    }
    
        @Entity
    @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "orgId")
    @JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" })
    @SuppressWarnings("serial")
    public class Org implements java.io.Serializable {
        @Id
        @Column(name = "orgId")
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private BigDecimal orgId;   
        private BigDecimal parentOrgId;
        @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "langId",scope=Lang.class)
        public Org() {
        }
        public Org(BigDecimal orgId, BigDecimal parentOrgId, Lang lang) {
            this.orgId = orgId;
            this.parentOrgId = parentOrgId;
            this.lang = lang;
        }
        public BigDecimal getOrgId() {
            return this.orgId;
        }
        public void setOrgId(BigDecimal orgId) {
            this.orgId = orgId;
        }
        public BigDecimal getParentOrgId() {
            return this.parentOrgId;
        }
        public void setParentOrgId(BigDecimal parentOrgId) {
            this.parentOrgId = parentOrgId;
        }
        @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
        public Lang getLang() {
            return this.lang;
        }
        public void setLang(Lang lang) {
            this.lang = lang;
        }
    }
    
  • 我的HBM Xml文件

    Org.hbm.xml

        <hibernate-mapping package="com.test.entity">
        <class name="com.test.entity.Org" table="ORG">
        <id name="orgId" type="big_decimal">
            <column name="ORG_ID" precision="22" scale="0" />
            <generator class="increment" />
        </id>        
        <property name="parentOrgId" type="big_decimal">
            <column name="PARENT_ORG_ID" precision="22" scale="0" not-null="true" />
        </property>
        <many-to-one name="lang" class="com.test.entity.Lang" fetch="select">
            <column name="LANG_ID" precision="22" scale="0" not-null="true" />
        </many-to-one>        
        </class>
    </hibernate-mapping>
    
        <hibernate-mapping package="com.test.entity">
        <class name="com.test.entity.Lang" table="LANG">
        <id name="langId" type="big_decimal">
            <column name="LANG_ID" precision="22" scale="0" />
            <generator class="increment" />
        </id>
        <property name="langName" type="string">
            <column name="LANG_NAME" length="32" not-null="true" unique="true" />
        </property>
        <set name="orgs" table="ORG" inverse="true" lazy="true" fetch="select">
            <key>
            <column name="LANG_ID" precision="22" scale="0" not-null="true" />
            </key>
            <one-to-many class="com.test.entity.Org" />
        </set>
        </class>
    </hibernate-mapping>
    
  • 此处货币也与相同,将其货币Id引用到货币
  • 我无法获取数组中的第二和第三个组织数据,它有Lang.Orgs和Lang.Orgs.Currency两种版本

  • 请帮忙,谢谢


  • 这将让您开始,我正在使用Spring JPA2和Hibernate以及Jackson

    我让Hibernate从实体创建表

    Spring应用程序上下文如下所示:

    <?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:jdbc="http://www.springframework.org/schema/jdbc"
        xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:cache="http://www.springframework.org/schema/cache"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
    
        <context:component-scan base-package="com.greg" />
        <tx:annotation-driven />
        <jpa:repositories base-package="com.greg.repository" />
    
        <bean id="dataSource"
            class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="org.h2.Driver" />
            <property name="url" value="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1" />
            <property name="username" value="sa" />
            <property name="password" value="" />
        </bean>
    
        <bean id="entityManagerFactory"
            class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="packagesToScan" value="com.greg.entity" />
            <property name="jpaVendorAdapter">
                <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
            </property>
            <property name="jpaProperties">
                <props>
                    <prop key="hibernate.hbm2ddl.auto">create</prop>
                    <prop key="hibernate.show_sql">false</prop>
                    <prop key="hibernate.format_sql">false</prop>
                    <prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
                </props>
            </property>
        </bean>
    
        <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
            <property name="entityManagerFactory" ref="entityManagerFactory" />
        </bean>
    
    </beans>
    
    这将创建问题中的表格

    Spring JPA存储库很简单:

    @Repository
    @Transactional
    public interface OrgRepository extends CrudRepository<Org, Long> {
    }
    
    我的测试是:

        @Test
    @Transactional
    public void test1() {
    
        try {
            Lang lang = makeLang("EN");
            langRepository.save(lang);
            assertNotNull(lang.getLangId());
    
            Org org1 = new Org();
            org1.setLang(lang);
            orgRepository.save(org1);
    
            Org org2 = new Org();
            org2.setLang(lang);
            org2.setParent(org1);
            orgRepository.save(org2);
    
            Org org3 = new Org();
            org3.setLang(lang);
            org3.setParent(org2);
            orgRepository.save(org3);
    
            assertEquals("EN", orgRepository.findOne(org1.getOrgId()).getLang().getLangName());
            assertNull(orgRepository.findOne(org1.getOrgId()).getParent());
    
            assertEquals("EN", orgRepository.findOne(org2.getOrgId()).getLang().getLangName());
            assertEquals(org1.getOrgId().longValue(), orgRepository.findOne(org2.getOrgId()).getParent().getOrgId().longValue());
    
            assertEquals("EN", orgRepository.findOne(org3.getOrgId()).getLang().getLangName());
            assertEquals(org2.getOrgId().longValue(), orgRepository.findOne(org3.getOrgId()).getParent().getOrgId().longValue());
    
            System.out.println(new ObjectMapper().writeValueAsString(org3));
    
            showTables("ORG");
            showTables("LANG");
        } catch (Exception e) {
            e.printStackTrace();
            fail();
        }
    }
    
    private Lang makeLang(String name) {
        Lang lang = new Lang();
        lang.setLangName(name);
        return lang;
    }
    

    请提供控制器方法的代码
    getAllChildWithParetOrgs(parentId)。那会更有帮助。另外,根据我对hibernate查询连接和数据库快照的理解,我认为JSON输出不应该再登记记录。请查看以下解释:

    因为您传递的parentId为0。根据hibernate查询联接和数据库快照,似乎没有OrgId=0的单独记录。 从子句的parentOrgId=0部分,它指的是子项:orgId为1的记录。 随后,它指的是orgId=1的子记录,即parentOrgId=1的记录,即orgId=2orgId=3的记录。我不认为你的JSON对象应该在那之后获得更多的结果

    @Entity
    public class Org {
    
        @Id
        @Column(name = "org_id")
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long orgId;
    
        @ManyToOne(fetch = FetchType.EAGER)
        @JoinColumn(name = "lang_id", referencedColumnName = "lang_id", updatable = false, insertable = false, nullable = false)
        private Lang lang;
    
        @ManyToOne(fetch = FetchType.EAGER)
        @JoinColumn(name = "parent_id", referencedColumnName = "org_id", updatable = false, insertable = false, nullable = false)
        private Org parent;
    
    @Repository
    @Transactional
    public interface OrgRepository extends CrudRepository<Org, Long> {
    }
    
    @Repository
    @Transactional
    public interface OrgRepository extends CrudRepository<Lang, Long> {
    }
    
        {
        "orgId": 4,
        "lang": {
            "langId": 1,
            "langName": "EN",
            "orgs": null
        },
        "parent": {
            "orgId": 3,
            "lang": {
                "langId": 1,
                "langName": "EN",
                "orgs": null
            },
            "parent": {
                "orgId": 2,
                "lang": {
                    "langId": 1,
                    "langName": "EN",
                    "orgs": null
                },
                "parent": null
            }
        }
    }
    
        @Test
    @Transactional
    public void test1() {
    
        try {
            Lang lang = makeLang("EN");
            langRepository.save(lang);
            assertNotNull(lang.getLangId());
    
            Org org1 = new Org();
            org1.setLang(lang);
            orgRepository.save(org1);
    
            Org org2 = new Org();
            org2.setLang(lang);
            org2.setParent(org1);
            orgRepository.save(org2);
    
            Org org3 = new Org();
            org3.setLang(lang);
            org3.setParent(org2);
            orgRepository.save(org3);
    
            assertEquals("EN", orgRepository.findOne(org1.getOrgId()).getLang().getLangName());
            assertNull(orgRepository.findOne(org1.getOrgId()).getParent());
    
            assertEquals("EN", orgRepository.findOne(org2.getOrgId()).getLang().getLangName());
            assertEquals(org1.getOrgId().longValue(), orgRepository.findOne(org2.getOrgId()).getParent().getOrgId().longValue());
    
            assertEquals("EN", orgRepository.findOne(org3.getOrgId()).getLang().getLangName());
            assertEquals(org2.getOrgId().longValue(), orgRepository.findOne(org3.getOrgId()).getParent().getOrgId().longValue());
    
            System.out.println(new ObjectMapper().writeValueAsString(org3));
    
            showTables("ORG");
            showTables("LANG");
        } catch (Exception e) {
            e.printStackTrace();
            fail();
        }
    }
    
    private Lang makeLang(String name) {
        Lang lang = new Lang();
        lang.setLangName(name);
        return lang;
    }