0

我在父(@OneToMany mappedBy)和它的子(@ManyToOne)之间有关系。当我尝试使用 QBE 根据父母检索孩子时,我总是会取回孩子的完整列表。

我附上了演示程序的源代码(pom.xml、hibernate.cfg.xml、logback.xml(以减少噪音)和 App.java(也包含@Entity)。

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

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Example;

public class App {

    Parent parentOfInterest ;

    public App() {
        populate();
        query();
        HibernateUtil.shutdown();
        System.exit(0);
    }

    public void populate() {
        Session session = HibernateUtil.getSessionFactory().openSession();
        session.beginTransaction();
        Parent[] parents = new Parent[3];
        for (int i = 0; i < parents.length; ++i)
            session.save(parents[i] = new Parent());
        for (int i = 0; i < parents.length * 3; ++i)
            session.save(new Child(parents[i % 3], i));
        parentOfInterest=parents[0];
        session.getTransaction().commit();
    }

    public void query() {
        Session session = HibernateUtil.getSessionFactory().openSession();
        session.beginTransaction();
        Example example = Example.create(new Child(parentOfInterest, null));
        @SuppressWarnings("deprecation")
        Criteria crit = session.createCriteria(Child.class);
        crit.add(example);
        @SuppressWarnings("unchecked")
        List<Child> children = crit.list();
        System.out
            .println("--------------------------------------------------");
        System.out
            .println("You should only see childen with seqno's of 0,3,6 ");
        children.forEach(c -> System.out.println(c.toString()));
        System.out
            .println("--------------------------------------------------");
        session.getTransaction().commit();
    }

    @SuppressWarnings("unused")
    public static void main(String[] args) {
        new App();
    }
}

@Entity
class Parent {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(unique = true, nullable = false)
    Integer id;

    @OneToMany(mappedBy = "parent")
    Set<Child> children = new HashSet<Child>(0);

    @Override
    public String toString() {
        return "Parent [id=" + id + "]";
    }

}

@Entity
class Child {

    public Child() {
    }

    public Child(Parent parent, Integer seqno) {
        this.parent = parent;
        this.seqno = seqno;
        if (parent != null)
            parent.children.add(this);
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(unique = true, nullable = false)
    Integer id;

    @ManyToOne(optional = false)
    @JoinColumn(nullable = false)
    Parent parent;

    Integer seqno;

    @Override
    public String toString() {
        return "Child [id=" + id + ", parent=" + parent + ", seqno=" + seqno
            + "]";
    }

}

class HibernateUtil {

    private static final SessionFactory SESSIONFACTORY = buildSessionFactory();

    private static SessionFactory buildSessionFactory() {
        try {
            return new Configuration().configure() // Create from
                                                   // hibernate.cfg.xml
                .buildSessionFactory();
        } catch (Throwable e) {
            e.printStackTrace(); // Log the exception, as it might be swallowed
            throw new ExceptionInInitializerError(e);
        }
    }

    public static SessionFactory getSessionFactory() {
        return SESSIONFACTORY;
    }

    public static void shutdown() {
        getSessionFactory().close(); // Close caches and connection pools
    }
}

这是hibernate.cfg.xml:

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">org.h2.Driver</property>
        <property name="hibernate.connection.url">jdbc:h2:file:./HibernateQBE</property>
        <property name="hibernate.connection.username">sa</property>
        <property name="hibernate.connection.password">sa</property>
        <property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>
<!--        <property name="show_sql">true</property> -->
<!--        <property name="format_sql">true</property> -->
        <property name="hibernate.hbm2ddl.auto">create</property>
        <mapping class="Parent" />
        <mapping class="Child" />
    </session-factory>
</hibernate-configuration>

这是 logback.xml:

<?xml version="1.0" encoding="UTF-8"?>

<configuration>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <Pattern>
                %d{yyyy-MM-dd_HH:mm:ss.SSS} %-5level %logger{36} - %msg%n
            </Pattern>
        </encoder>
    </appender>

    <appender name="FILE"
        class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>./HibernateExample.log</file>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <Pattern>
                %d{yyyy-MM-dd_HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
            </Pattern>
        </encoder>

        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
            <FileNamePattern>./HibernateQBE.%i.log.zip</FileNamePattern>
            <MinIndex>1</MinIndex>
            <MaxIndex>10</MaxIndex>
        </rollingPolicy>

        <triggeringPolicy
            class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>2MB</MaxFileSize>
        </triggeringPolicy>

    </appender>

    <logger name="org.hibernate.type" level="WARN" />
    <logger name="org.hibernate" level="WARN" />

    <root level="INFO">
        <!-- <appender-ref ref="FILE" /> -->
        <appender-ref ref="STDOUT" />
    </root>

</configuration>

这是 pom.xml:

<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 
        http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.diezil</groupId>
    <artifactId>hibernate.qbe</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <h2.version>1.4.195</h2.version>
        <hibernate-core.version>5.2.10.Final</hibernate-core.version>
        <logback.version>0.9.28</logback.version>
        <mainClass>App</mainClass>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>${hibernate-core.version}</version>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>${h2.version}</version>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>${logback.version}</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>${logback.version}</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.0.0</version>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals><goal>single</goal></goals>
                    </execution>
                </executions>
                <configuration>
                    <appendAssemblyId>false</appendAssemblyId>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <mainClass>${mainClass}</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>
4

0 回答 0