我正在尝试在两个实体之间应用一对一的关系 第一个实体: 视频和组织视频 每个组织视频都有一个视频实体
所以我做了以下事情
第一个organization_video表格
CREATE TABLE `organization_video` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
视频表格
CREATE TABLE `video` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`title` varchar(100) DEFAULT NULL,
// rest of table contents
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
然后我在organization_video表中添加了约束
CONSTRAINT `FK_organization_video` FOREIGN KEY (`id`) REFERENCES `video` (`id`)
然后生成实体
Video.java
@Entity
@Table(name = "video")
public class Video extends Persistable<Long> {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Long id;
@OneToOne(cascade = CascadeType.ALL, mappedBy = "video")
private OrganizationVideo organizationVideo;
\\ rest of video contetns
}
OrganizationVideo.java
@Entity
@Table(name = "organization_video")
public class OrganizationVideo extends Persistable<Long> {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Long id;
@JoinColumn(name = "id", referencedColumnName = "id")
@OneToOne(optional = false)
private Video video;
\\ rest of organziation video contents
}
持久性.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="Default_Persistence_Unit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<non-jta-data-source>jdbc/defaultDataSource</non-jta-data-source>
<properties>
<property name="hibernate.transaction.auto_close_session" value="false"/>
<property name="hibernate.max_fetch_depth" value="0"/>
<property name="hibernate.connection.release_mode" value="auto"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<property name="hibernate.cglib.use_reflection_optimizer" value="true"/>
</properties>
</persistence-unit>
</persistence>
持久化对象时一切正常 问题出在获取查询上
StringBuilder queryStr = new StringBuilder("select v from Video v where v.organizationVideo is null");
Query query = getEntityManager().createQuery(queryStr.toString());
return query.getResultList();
奇怪的行为是,此查询获取数据一次,然后不获取任何尝试使用 @PrimaryKeyJoinColumn
并更改 id
生成类型的数据,但没有成功,但确实存在有问题,当我尝试从查询中删除 is null
时,第一次看到数据会很奇怪,它会获取数据,但将 null 值分配给 OrganizationVideo
那么为什么查询没有除非第一次,否则无法工作。
最佳答案
您必须检查为查询生成的 SQL,但我猜测由于 ID 是外键并且是自动生成的,因此插入实体会导致查询出现问题。首先尝试修复您的模型:
OrganizationVideo ID 需要通过视频关系设置(如果使用 JPA 2.0):
@Entity
@Table(name = "organization_video")
public class OrganizationVideo extends Persistable<Long> {
@Id
@JoinColumn(name = "id", referencedColumnName = "id")
@OneToOne(optional = false)
private Video video;
\\ rest of organziation video contents
}
或者您在 OrganizationVideo 中创建 ID 映射之一 insertable=false、updatable=false。如果您这样做,那么您必须自己在应用程序内的 OrganizationVideo 中设置其他字段,并且仅在为 Video 实例分配了 ID 值之后。由于您使用的是身份,这意味着您必须保留视频、刷新,然后在 OrganizationVideo 中使用该值,然后才能保留它。
如果您只需向 OrganizationVideo 表添加外键并使用它来引用视频 ID,那么您的模型会更容易。
关于java - 一对一关系选择查询仅第一次获取一次数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31926122/