我在 Java 应用程序中使用 Hibernate 通过主键从数据库中检索 Alien 对象。但是,即使我知道数据库中存在该记录,检索到的对象仍为空。这是我的代码:
package com.hks.DemoHib;
import java.util.Collection;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
public class App {
public static void main(String[] args) {
Configuration con = new Configuration().configure().addAnnotatedClass(Laptop.class).addAnnotatedClass(Alien.class);
SessionFactory sf = con.buildSessionFactory();
Session session = sf.openSession();
session.beginTransaction();
Alien a1 = session.get(Alien.class, 1);
if (a1 == null) {
System.out.println("Alien with ID 1 not found!");
} else {
a1.setAname("Harsh");
System.out.println(a1.getAname());
Collection<Laptop> laps = a1.getLaps();
for (Laptop l : laps) {
System.out.println(l);
}
}
session.getTransaction().commit();
}
}
这是我的实体类:
外星人.java
import javax.persistence.*;
import java.util.Collection;
@Entity
@Table(name = "Alien")
public class Alien {
@Id
private int aid;
private String aname;
@OneToMany(mappedBy = "alien")
private Collection<Laptop> laps;
// Getters and Setters
}
笔记本电脑.java
import javax.persistence.*;
@Entity
@Table(name = "Laptop")
public class Laptop {
@Id
private int lid;
private String lname;
@ManyToOne
@JoinColumn(name = "aid")
private Alien alien;
// Getters and Setters
}
hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/your_database</property>
<property name="hibernate.connection.username">your_username</property>
<property name="hibernate.connection.password">your_password</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="show_sql">true</property>
<mapping class="com.hks.DemoHib.Alien"/>
<mapping class="com.hks.DemoHib.Laptop"/>
</session-factory>
</hibernate-configuration>
我检查了数据库,确认有一条主键为 1 的 Alien 记录。尽管如此,session.get 方法还是返回 null。
餐桌外星人
帮助名字 1 纳文 2 拉胡尔 3 玛雅克
可能的原因是什么?我该如何解决?
注意事项:
我无法生成问题中描述的错误。
以下代码是可以正常执行的代码。
├── pom.xml
└── src
└── main
├── java
│ └── com
│ └── hks
│ └── DemoHib
│ ├── Alien.java
│ ├── App.java
│ └── Laptop.java
└── resources
└── hibernate.cfg.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>
<groupId>com.hks.DemoHib</groupId>
<artifactId>testapp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>testapp</name>
<description>hibernate</description>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<hibernate.version>5.4.33.Final</hibernate.version>
<mysql.connector.version>8.0.33</mysql.connector.version>
</properties>
<dependencies>
<!-- Hibernate Core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<!-- MySQL Connector -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>${mysql.connector.version}</version>
</dependency>
</dependencies>
</project>
我将
hibernate.dialect
修改为org.hibernate.dialect.MySQL5Dialect
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!--
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/your_database</property>
<property name="hibernate.connection.username">your_username</property>
<property name="hibernate.connection.password">your_password</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<mapping class="com.hks.DemoHib.Alien"/>
<mapping class="com.hks.DemoHib.Laptop"/>
</session-factory>
</hibernate-configuration>
我将
Collection
修改为List
。
package com.hks.DemoHib;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@Entity
@Table(name = "Alien")
public class Alien {
@Id
private int aid;
private String aname;
@OneToMany(mappedBy = "alien", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Laptop> laps = new ArrayList<>();
public int getAid() {
return aid;
}
public void setAid(int aid) {
this.aid = aid;
}
public String getAname() {
return aname;
}
public void setAname(String aname) {
this.aname = aname;
}
public List<Laptop> getLaps() {
return laps;
}
public void setLaps(List<Laptop> laps) {
this.laps = laps;
}
public void addLaptop(Laptop laptop) {
this.laps.add(laptop);
laptop.setAlien(this); //IMPORTANT
}
public void removeLaptop(Laptop laptop) {
this.laps.remove(laptop);
laptop.setAlien(null); //IMPORTANT
}
}
package com.hks.DemoHib;
import javax.persistence.*;
@Entity
@Table(name = "Laptop")
public class Laptop {
@Id
private int lid;
private String lname;
@ManyToOne
@JoinColumn(name = "aid")
private Alien alien;
public int getLid() {
return lid;
}
public void setLid(int lid) {
this.lid = lid;
}
public String getLname() {
return lname;
}
public void setLname(String lname) {
this.lname = lname;
}
public Alien getAlien() {
return alien;
}
public void setAlien(Alien alien) {
this.alien = alien;
}
}
package com.hks.DemoHib;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class App {
public static void main(String[] args) {
Configuration con = new Configuration().configure().addAnnotatedClass(Laptop.class).addAnnotatedClass(Alien.class);
SessionFactory sf = con.buildSessionFactory();
Session session = sf.openSession();
session.beginTransaction();
Alien alien1 = new Alien();
alien1.setAid(1);
alien1.setAname("Navin");
Laptop laptop1 = new Laptop();
laptop1.setLid(1);
laptop1.setLname("AAA");
Laptop laptop2 = new Laptop();
laptop2.setLid(2);
laptop2.setLname("BBB");
alien1.addLaptop(laptop1);
alien1.addLaptop(laptop2);
session.save(alien1);
Alien alien2 = new Alien();
alien2.setAid(2);
alien2.setAname("Rahul");
Alien alien3 = new Alien();
alien3.setAid(3);
alien3.setAname("Mayank");
session.save(alien2);
session.save(alien3);
session.getTransaction().commit();
session.beginTransaction();
Alien a1 = session.get(Alien.class, 1);
if (a1 == null) {
System.out.println("Alien with ID 1 not found!");
} else {
a1.setAname("Harsh");
System.out.println(a1.getAname());
List<Laptop> laps = a1.getLaps();
for (Laptop l : laps) {
//System.out.println(l);
System.out.println(l.getLid() + " " + l.getLname() + " " + l.getAlien().getAid());
}
}
session.save(a1);
session.getTransaction().commit();
}
}
mvn clean package
mvn dependency:copy-dependencies -DoutputDirectory=target/libs
java -cp "target/libs/*:target/testapp-0.0.1-SNAPSHOT.jar" com.hks.DemoHib.App
$ java -cp "target/libs/*:target/testapp-0.0.1-SNAPSHOT.jar" com.hks.DemoHib.App
7月 25, 2024 2:24:57 下午 org.hibernate.Version logVersion
INFO: HHH000412: Hibernate ORM core version 5.4.33.Final
7月 25, 2024 2:24:57 下午 org.hibernate.boot.jaxb.internal.stax.LocalXmlResourceResolver resolveEntity
WARN: HHH90000012: Recognized obsolete hibernate namespace http://hibernate.sourceforge.net/hibernate-configuration. Use namespace http://www.hibernate.org/dtd/hibernate-configuration instead. Support for obsolete DTD/XSD namespaces may be removed at any time.
7月 25, 2024 2:24:57 下午 org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
7月 25, 2024 2:24:57 下午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH10001002: Using Hibernate built-in connection pool (not for production use!)
7月 25, 2024 2:24:57 下午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001005: using driver [com.mysql.cj.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/your_database]
7月 25, 2024 2:24:57 下午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001001: Connection properties: {password=****, user=your_username}
7月 25, 2024 2:24:57 下午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001003: Autocommit mode: false
7月 25, 2024 2:24:57 下午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PooledConnections <init>
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
7月 25, 2024 2:24:57 下午 org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
7月 25, 2024 2:24:58 下午 org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@df921b1] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
Hibernate:
create table Alien (
aid integer not null,
aname varchar(255),
primary key (aid)
) engine=MyISAM
Hibernate:
create table Laptop (
lid integer not null,
lname varchar(255),
aid integer,
primary key (lid)
) engine=MyISAM
Hibernate:
alter table Laptop
add constraint FK6ov7gtqxs02wr7p13bn8u6whh
foreign key (aid)
references Alien (aid)
7月 25, 2024 2:24:58 下午 org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator initiateService
INFO: HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
Hibernate:
select
laptop_.lid,
laptop_.aid as aid3_1_,
laptop_.lname as lname2_1_
from
Laptop laptop_
where
laptop_.lid=?
Hibernate:
select
laptop_.lid,
laptop_.aid as aid3_1_,
laptop_.lname as lname2_1_
from
Laptop laptop_
where
laptop_.lid=?
Hibernate:
insert
into
Alien
(aname, aid)
values
(?, ?)
Hibernate:
insert
into
Laptop
(aid, lname, lid)
values
(?, ?, ?)
Hibernate:
insert
into
Laptop
(aid, lname, lid)
values
(?, ?, ?)
Hibernate:
insert
into
Alien
(aname, aid)
values
(?, ?)
Hibernate:
insert
into
Alien
(aname, aid)
values
(?, ?)
Harsh
1 AAA 1
2 BBB 1
Hibernate:
update
Alien
set
aname=?
where
aid=?
Harsh
1 AAA 1
2 BBB 1
表:外星人
桌子:笔记本电脑