我在父(@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>