jpa语法错误_JPA陷阱/错误

jpa语法错误

根据我在帮助团队和进行培训方面的经验,这是我遇到的一些陷阱/错误,它们在使用JPA的基于Java的系统中引起了一些问题。

  • 需要一个公共的无参数构造函数
  • 始终使用双向关联/关系
  • @OneToMany用于可能庞大的集合

需要一个公共的无参数构造函数

是的,JPA @Entity需要零参数(或默认的无参数)构造函数。 但这可以得到protected 您不必将其public 这样就可以实现更好的面向对象的建模,因为您不必强制使用可公开访问的零参数构造函数。

实体类必须具有无参数构造函数。 实体类也可以具有其他构造函数。 no-arg构造函数必须是public 或protected 。 [强调我的]

–摘自Java Persistence API 2.1规范(Oracle)的2.1

如果要建模的实体在创建时有一些字段需要初始化,则应通过其构造函数来完成。

注意:一些JPA提供程序可以通过在构建时添加一个无参数的构造函数来克服缺失的无参数构造函数。

假设我们正在建模酒店房间预订系统。 在其中,我们可能有诸如房间,预订等之类的实体。预订实体可能需要开始日期和结束日期,因为没有停留时间来创建一个预订实体就没有多大意义。 在保留的构造函数中将开始日期和结束日期作为参数包括在内,将可以提供更好的模型。 保留受保护的零参数构造函数会使JPA满意。

@Entity
public class Reservation { ...public Reservation(RoomType roomType, DateRange startAndEndDates) {if (roomType == null || startAndEndDates == null) {throw new IllegalArgumentException(...);} ...}...protected Reservation() { /* as required by ORM/JPA */ }
}

注意: Hibernate(JPA提供程序)允许将零参数构造函数设为私有。 这使您的JPA代码不可移植到其他JPA提供程序。

它还有助于在零参数构造函数中添加注释,以表明它是出于JPA目的(技术基础结构)而添加的,并且不是域所必需的(业务规则/逻辑)。

尽管我在JPA 2.1规范中找不到它,但可嵌入类也需要一个默认(无参数)构造函数。 就像实体一样,可以将必需的无参数构造函数设为protected

@Embeddable
public class DateRange { ...public DateRange(Date start, Date end) {if (start == null || end == null) {throw new IllegalArgumentException(...);}if (start.after(end)) {throw new IllegalArgumentException(...);} ...}...protected DateRange() { /* as required by ORM/JPA */ }
}

DDD示例项目还通过将no-arg构造函数设置为包范围来隐藏no-arg构造函数(请参阅Cargo实体类,其中no-arg构造函数位于底部附近)。

始终使用双向关联/关系

JPA上的教学材料通常显示出双向关联。 但这不是必需的。 例如,假设我们有一个包含一个或多个项目的订单实体。

@Entity
public class Order {@Id private Long id;@OneToMany private List<OrderItem> items;...
}@Entity
public class OrderItem {@Id private Long id;@ManyToOne private Order order;...
}

很高兴知道JPA支持双向关联。 但是实际上,这成为维护的噩梦。 如果订单项不必知道其父订单对象,则单向关联就足够了(如下所示)。 ORM只需要知道如何命名多边表中的外键列。 通过在关联的一侧添加@JoinColumn批注来提供此功能。

@Entity
public class Order {@Id Long id;@OneToMany@JoinColumn(name="order_id", ...)private List<OrderItem> items;...
}@Entity
public class OrderItem {@Id private Long id;// @ManyToOne private Order order;...
}

由于OrderItem不再需要保留对Order实体的引用,因此使其变得单向变得更容易。

请注意,有时可能需要双向关联。 实际上,这种情况很少见。

这是另一个例子。 假设您有几个引用国家/地区实体的实体(例如,人的出生地,邮寄地址等)。 显然,这些实体将引用国家实体。 但是,国家是否必须引用所有这些不同的实体? 很有可能,不是。

@Entity
public class Person {@Id Long id;@ManyToOne private Country countryOfBirth;...
}@Entity
public class PostalAddress {@Id private Long id;@ManyToOne private Country country;...
}@Entity
public class Country {@Id ...;// @OneToMany private List<Person> persons;// @OneToMany private List<PostalAddress> addresses;
}

所以,仅仅因为JPA支持双向关联, 并不意味着你必须!

使用

假设您正在建模银行帐户及其交易。 随着时间的流逝,一个帐户可以进行数千(甚至数百万)笔交易。

@Entity
public class Account {@Id Long id;@OneToMany@JoinColumn(name="account_id", ...)private List<AccountTransaction> transactions;...
}@Entity
public class AccountTransaction {@Id Long id;...
}

对于只有少量交易的帐户,似乎没有任何问题。 但是随着时间的流逝,当一个帐户包含成千上万个(如果不是上百万个)交易时,您很可能会遇到内存不足的错误。 那么,有什么更好的映射方法呢?

如果不能确保关联的多面中的最大元素数都可以全部加载到内存中,则最好在@ManyToOne的另一侧使用@ManyToOne

@Entity
public class Account {@Id Long id;// @OneToMany private List<AccountTransaction> transactions;...
}@Entity
public class AccountTransaction {@Id Long id;@ManyToOneprivate Account account;...public AccountTransaction(Account account, ...) {...}protected AccountTransaction() { /* as required by ORM/JPA */ }
}

要检索一个帐户可能数千(如果不是几百万)的交易,请使用支持分页的存储库。

@Transactional
public interface AccountTransactionRepository {Page<AccountTransaction> findByAccount(Long accountId, int offset, int pageSize);...
}

要支持分页,请使用Query对象的setFirstResult(int)setMaxResults(int)方法。

摘要

我希望这些说明可以帮助开发人员避免犯这些错误。 总结一下:

  • 要求公众。 JPA要求的无参数构造函数可以设为publicprotected 。 如果需要,可以考虑对其进行protected
  • 一直使用 考虑单向而不是双向关联/关系。
  • 使用 避免使用@OneToMany收集可能庞大的集合。 考虑@ManyToOne映射关联/关系的@ManyToOne端,并支持分页。

翻译自: https://www.javacodegeeks.com/2016/02/jpa-pitfalls-mistakes.html

jpa语法错误

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/336660.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python源码文件以什么格式结尾结尾_查看python源码,发现里面的函数都以pass结尾,那么意义何在?...

例如&#xff1a;class str(object):"""str(object) -> strstr(bytes_or_buffer[, encoding[, errors]]) -> strCreate a new string object from the given object. If encoding orerrors is specified, then the object must expose a data bufferthat …

java流式传输对象_使用Java 8在地图上流式传输

java流式传输对象在本文中&#xff0c;我将向您展示如何在标准Java映射上有效地实现Speedment Open Source流&#xff0c;并将Stream接口扩展为MapStream&#xff01; 即使在复杂的情况下&#xff0c;此添加将使保持流的具体性和可读性变得更加容易。 希望这将允许您继续流式传…

计算机学术硕士课题,硕士学术论文选题的原则分析

硕士学术论文选题的原则分析选题作为硕士学术论文写作过程的第一步&#xff0c;也是最关键的一步&#xff0c;直接影响到论文写作整个过程中&#xff0c;包括资料收集&#xff0c;发现问题&#xff0c;解决问题等一系列工作&#xff0c;决定了整篇论文的成败。硕士学术论文是对…

选择排序与冒泡排序的区别

冒泡排序&#xff1a;冒泡排序&#xff08;BubbleSort&#xff09;的基本概念是&#xff1a;依次比较相邻的两个数&#xff0c;将小数放在前面&#xff0c;大数放在后面。即在第一趟&#xff1a;首先比较第1个和第2个数&#xff0c;将小数放前&#xff0c;大数 放后。然后比较第…

冒泡排序 自带时间复杂度测试

#include<iostream> #include<time.h> using namespace std;void Sort(int List[], int n);int main() {int a[10000];int k, j;// 设置种子srand((unsigned)time(NULL));/* 生成 10 个随机数 */for (k 0; k < 10000; k){// 生成实际的随机数j rand();a[k] j…

独占线程太多怎么办_电脑内存被占用太多怎么办?

1、禁用闲置的IDE通道右键点击“我的电脑-属性”&#xff0c;然后点击“硬件”接着点击“设备管理器”&#xff0c;在其中打开“IDE ATA/PATA控制器”然后分别进入主要和次要IDE通道&#xff0c;选择“高级设置”&#xff0c;在这里找到“当前传送模式”为“不适用”的一项&…

计算机net use命令使用,网络命令net之net use应用

echo offnet use LPT1: "123456" /user:pingpai /persistent:no以上为批处理文件 "打印.bat"脚本。先介绍net use命令&#xff0c;最后看这个脚本是什么意思。以下内容来自net help use的结果。C:\Documents and Settings\ppb>net help use此命令的语…

记录日志的测试软件_教程:测试期间的日志记录

记录日志的测试软件日志记录是一种流行的解决方案&#xff0c;用于显示软件在运行时的运行状况。 但是&#xff0c;当我们使用jUnit / TestNG对应用程序进行单元测试时&#xff0c;日志记录会怎样&#xff1f; 在自动化测试执行期间&#xff0c;我们通常不希望看到日志记录消…

选择排序 自带时间复杂度分析

从当前未排序的整数中找到最小的整数&#xff0c;将它放在已排序的整数列表的最后。 #include<iostream> #include<time.h> using namespace std;void Sort(int List[], int n);int main() {int a[10000];int k, j;// 设置种子srand((unsigned)time(NULL));/* 生成…

oracle11g支持xp吗_拔掉U盘前一定需要安全弹出吗?

相信每一个使用过U盘的人&#xff0c;都经历过不安全弹出USB设备就直接拔掉&#xff0c;然后被电脑无情提示没有正确弹出USB设备的状况。拔掉U盘前点击安全弹出&#xff0c;已经成了一种默认的操作。那么&#xff0c;问题来了&#xff0c;拔掉U盘前真的需要安全弹出吗&#xff…

yili邮箱服务器配置,手把手教 个人SMTP服务器的配置 -电脑资料

导读&#xff1a;&#xff0c;因此我们要手工添加&#xff0c;管理员身份登录Windows Server 2003 系统。依次进入“控制面板→添加或删除程序→添加/删除Windows组件”&#xff0c;在弹出的“Windows组件向导”对话框中选中“电子邮件服务”选项&#xff0c;点击“详细信息”按…

java中使用kotlin_在Kotlin中使用libGDX

java中使用kotlin最近&#xff0c;我一直在阅读有关不同语言的信息&#xff0c;以及它们可以为已经拥挤的软件开发人员带来什么&#xff0c;并且一种语言对我来说很突出&#xff1a;Kotlin。 &#xff08; https://kotlinlang.org/ &#xff09; 这是一种相对较新的语言&#…

单链表的各种操作

#include<iostream> #define _CRT_SECURE_NO_WARNINGS using namespace std; typedef int DATA;struct SNode //定义节点 {DATA data;SNode* pNext; }; class CList //创建一个链表类 {SNode* m_hHead; //链表初始化char m_name[20];public:CL…

linux双显卡配置_Linux系统怎么配置双显卡?

感谢脚本之家网友鸢一雨音 的投稿众所周知&#xff0c;自从高性能独立图形处理器出现之后&#xff0c;很多便携式计算机就会采取一种双显卡的设计&#xff1a;节能的核心图形处理器用于渲染常规的桌面环境&#xff0c;而高性能的独立图形处理器则负责渲染高需求的应用程序。这种…

同时防服务器维修,加强服务器日常运维,避免宕机灾难发生

原标题&#xff1a;加强服务器日常运维&#xff0c;避免宕机灾难发生服务器作为我们日常网络的支撑&#xff0c;可以说是24小时的全天候运转。在这种无休止的“加班”的状态下&#xff0c;服务器必然容易出问题&#xff0c;一旦发生服务器宕机就会造成整个网络的瘫痪&#xff0…

java动态代理_Java动态代理

java动态代理代理是一种设计模式。 当我们想添加或修改现有类的某些功能时&#xff0c;我们创建并使用代理对象。 使用代理对象而不是原始对象。 通常&#xff0c;代理对象具有与原始对象相同的方法&#xff0c;并且在Java代理类中&#xff0c;通常会extend原始类。 代理具有原…

建立能持续处理请求的Server端改造

#include<iostream> #include<Windows.h> using namespace std;int main() {//初始化ws2_32.dllWORD ver MAKEWORD(2, 2);WSADATA wsaData;WSAStartup(ver, &wsaData);//对应WSACleanup的调用//1.建立一个socketSOCKET _sock ::socket(AF_INET, SOCK_STREAM,…

basemap安装_【我是解决安装问题系列_1】Mac python basemap安装

「2020/3/21更新」 附basemap网盘下载地址⏬Python需要跳过的安装的坑太太太太多了!!!!!最近看《利用python进行数据分析》这本书&#xff0c;到可视化的部分&#xff0c;看着最后的例子地图挺酷炫的&#xff0c;跟着敲代码的过程中&#xff0c;发现有时候不是你不会写&#xf…

nfs服务器远程访问,NFS远程共享存储

原标题&#xff1a;NFS远程共享存储构建储NFS远程共享存因为NFS有很多功能&#xff0c;不同的功能需要使用不同的端口。因此NFS无法固定端口。而RPC会记录NFS端口的信息&#xff0c;这样就能够通过RPC实现服务端和客户端的RPC来沟通端口信息。那RPC和NFS之间又是如何之间相互通…

chameleon 算法_使用Chameleon,Shrinkwrap,Drone / Graphene与Arquillian进行Java EE集成测试...

chameleon 算法从我以前的帖子继续在这里 &#xff0c;我想我已经了解了Java EE和也的Arquillian&#xff0c;并测试了一些新的&#xff08;和令人兴奋的&#xff09;事&#xff0c;我想与大家分享。 但是&#xff0c;在开始之前&#xff0c;我想首先请您注意以下几点&#xf…