我在弹簧靴中热切地抓取一个小问题。基本上,我有一个实体定义为:
@Entity
class EventEntry(
@ID
val uid
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "event_to_boxes", joinColumns = arrayOf(JoinColumn(name = "event_uid")))
@Column(name = "box_uid")
val boxUids: List<Long>
) : EventEntry(userUid, timestamp)
现在,当我插入数据(来自graphql,但很详细)时,一切正常,并且我可以看到在数据库上,多行正确地保留在event_to_boxes表上。 不幸的是,当我检索所有事件时,突然出现了一些意外情况。
我看到的是查询所有事件的查询,然后对boxUids的每个列表询问一次,几乎就像FetchType.EAGER被完全忽略了。
我的理解是,在填充事件实体时,渴望获取类型的对象应该已经获得了框uid的值。 我有什么想念的吗?还是我的理解是完全错误的?
为了提供更多背景知识,我正在尝试以此方式建立N对N关系,这是N关系的一半,但是我必须在获取事件实体时也要提出框uid(框是关系的另一半),没有任何其他框数据
答案 0 :(得分:0)
如休眠documentation中所述,from PyQt5 import QtCore, QtGui, QtWidgets
#from afterlogin import Ui_afterloginwindow
class Ui_afterloginwindow(object):
def setupUi(self, afterloginwindow):
afterloginwindow.setObjectName("afterloginwindow")
afterloginwindow.resize(720, 480)
afterloginwindow.setMinimumSize(QtCore.QSize(720, 480))
afterloginwindow.setMaximumSize(QtCore.QSize(720, 480))
afterloginwindow.setStyleSheet("background-color: qlineargradient(spread:pad, x1:0, y1:0,\
x2:1, y2:1, stop:0 rgba(35, 226, 167, 255), stop:1 rgba(255, 255, 255, 255));")
self.centralwidget = QtWidgets.QWidget(afterloginwindow)
self.centralwidget.setObjectName("centralwidget")
self.newclient = QtWidgets.QPushButton(self.centralwidget)
self.newclient.setGeometry(QtCore.QRect(230, 120, 241, 91))
font = QtGui.QFont()
font.setFamily("Rockwell Extra Bold")
font.setPointSize(16)
font.setBold(True)
font.setWeight(75)
self.newclient.setFont(font)
self.newclient.setStyleSheet("background-color: qconicalgradient(cx:1, cy:0.875, angle:0,\
stop:0 rgba(255, 124, 0, 255), stop:1 rgba(255, 255, 255, 255));\n"
"background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:1, y2:1, stop:0.318182 rgba(226,\
198, 94, 255), stop:1 rgba(207, 207, 207, 255));")
self.newclient.setObjectName("newclient")
self.renew = QtWidgets.QPushButton(self.centralwidget)
self.renew.setGeometry(QtCore.QRect(230, 250, 241, 91))
font = QtGui.QFont()
font.setFamily("Rockwell Extra Bold")
font.setPointSize(15)
font.setBold(True)
font.setWeight(75)
self.renew.setFont(font)
self.renew.setStyleSheet("background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1,\
y2:1, stop:0 rgba(146, 237, 241, 255), stop:1 rgba(255, 255, 255, 255));")
self.renew.setObjectName("renew")
self.newcard = QtWidgets.QPushButton(self.centralwidget)
self.newcard.setGeometry(QtCore.QRect(230, 380, 241, 91))
font = QtGui.QFont()
font.setFamily("Rockwell Extra Bold")
font.setPointSize(15)
font.setBold(True)
font.setWeight(75)
self.newcard.setFont(font)
self.newcard.setStyleSheet("background-color: qconicalgradient(cx:0, cy:0, angle:135, stop:0 \
rgba(255, 255, 0, 69), stop:0.375 rgba(255, 255, 0, 69), stop:0.423533 rgba(251, 255, 0, 145), \
stop:0.45 rgba(247, 255, 0, 208), stop:0.477581 rgba(255, 244, 71, 130), stop:0.518717 rgba(255, \
218, 71, 130), stop:0.55 rgba(255, 255, 0, 255), stop:0.57754 rgba(255, 203, 0, 130), stop:0.625 \
rgba(255, 255, 0, 69), stop:1 rgba(255, 255, 0, 69));")
self.newcard.setObjectName("newcard")
self.rechercher = QtWidgets.QPushButton(self.centralwidget)
self.rechercher.setGeometry(QtCore.QRect(230, 10, 241, 81))
font = QtGui.QFont()
font.setFamily("Rockwell Extra Bold")
font.setPointSize(16)
font.setBold(True)
font.setWeight(75)
self.rechercher.setFont(font)
self.rechercher.setObjectName("rechercher")
afterloginwindow.setCentralWidget(self.centralwidget)
self.retranslateUi(afterloginwindow)
QtCore.QMetaObject.connectSlotsByName(afterloginwindow)
def retranslateUi(self, afterloginwindow):
_translate = QtCore.QCoreApplication.translate
afterloginwindow.setWindowTitle(_translate("afterloginwindow", "MainWindow"))
self.newclient.setText(_translate("afterloginwindow", "Nouveau Client "))
self.renew.setText(_translate("afterloginwindow", "Renouvellement "))
self.newcard.setText(_translate("afterloginwindow", "Nouvelle Carte "))
self.rechercher.setText(_translate("afterloginwindow", "Rechercher"))
class Ui_login(object):
def setupUi(self, login):
login.setObjectName("login")
login.resize(720, 480)
login.setMinimumSize(QtCore.QSize(720, 480))
login.setMaximumSize(QtCore.QSize(720, 480))
login.setStyleSheet("background-color: rgb(255, 255, 255);\n"
"background-color: rgb(255, 85, 0);")
self.centralwidget = QtWidgets.QWidget(login)
self.centralwidget.setObjectName("centralwidget")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(290, 390, 171, 71))
self.pushButton.setStyleSheet("background-color: rgb(255, 255, 255);")
self.pushButton.setObjectName("pushButton")
self.pushButton.clicked.connect(self.login)
self.username = QtWidgets.QLabel(self.centralwidget)
self.username.setGeometry(QtCore.QRect(170, 165, 161, 31))
self.username.setStyleSheet("background-color: rgb(255, 255, 255);")
self.username.setObjectName("username")
self.password = QtWidgets.QLabel(self.centralwidget)
self.password.setGeometry(QtCore.QRect(170, 225, 171, 41))
self.password.setStyleSheet("background-color: rgb(255, 255, 255);")
self.password.setObjectName("password")
self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit.setGeometry(QtCore.QRect(400, 170, 113, 20))
self.lineEdit.setStyleSheet("background-color: rgb(255, 255, 255);")
self.lineEdit.setObjectName("lineEdit")
self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit_2.setGeometry(QtCore.QRect(400, 240, 113, 20))
self.lineEdit_2.setStyleSheet("background-color: rgb(255, 255, 255);")
self.lineEdit_2.setObjectName("lineEdit_2")
login.setCentralWidget(self.centralwidget)
self.retranslateUi(login)
QtCore.QMetaObject.connectSlotsByName(login)
def retranslateUi(self, login):
_translate = QtCore.QCoreApplication.translate
login.setWindowTitle(_translate("login", "MainWindow"))
self.pushButton.setText(_translate("login", "login "))
self.username.setText(_translate("login", "username"))
self.password.setText(_translate("login", "password "))
class AfterLoginWindow(QtWidgets.QMainWindow, Ui_afterloginwindow):
def __init__(self):
super().__init__()
self.setupUi(self)
class MyWin(QtWidgets.QMainWindow, Ui_login):
def __init__(self):
super().__init__()
self.setupUi(self)
def login(self):
username = self.lineEdit.text()
password = self.lineEdit_2.text()
if username == "admin" and password == "admin":
self.window = AfterLoginWindow()
self.window.show()
self.hide()
else:
msg = QtWidgets.QMessageBox.information(None, 'Error', 'Something went wrong, try again.')
if __name__=="__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
myapp = MyWin()
myapp.show()
sys.exit(app.exec_())
仅适用于直接实体获取:
FetchType.EAGER
EventEntry eventEntry = entityManager.find(EventEntry.class, 1L);
子句已添加到生成的SQL查询中,因为需要热切地获取此关联。另一方面,如果您使用的实体查询不包含
LEFT JOIN
指令...Hibernate改为使用辅助选择。这是因为实体查询的提取策略无法被覆盖,因此Hibernate需要进行二次选择,以确保在将结果返回给用户之前,已提取
JOIN FETCH
关联。如果您忘记了
EAGER
的所有JOIN FETCH
关联,则Hibernate将为每个关联发出第二选择,从而导致N + 1查询问题。 / p>因此,您应该首选LAZY关联。