0

我有 2 张桌子赞助商和研究。赞助商和研究表中的列是:

赞助商表结构:

SponsorId: int primary key auto_increment,
SponsorName: varchar(30) unique not null,
Address: varchar(255)

学习桌结构:

StudyId int primary key auto_increment,
StudyName varchar(30) unique not null,
SponsorId int not null foreign key to Sponsors table. 

Study to Sponsor 具有多对一关系。

我正在尝试在数据表中显示赞助商和研究中的字段,并对其执行创建、更新和删除操作。

这是我用来填充数据表的方法。

public List retrieveStudy() {
  Query query=getEntityManager().createNativeQuery("select"+    
              "s.studyId,s.studyName,s.sponsorId ,sp.sponsorName as"+    
              "sponsorName,sp.address from Study s left join Sponsors sp", 
               Study.class);
    return query.getResultList();
}

在显示研究的数据表时,我想显示 SponsorName 而不是 SponsorId,因此,我使用了连接查询来获取 SponsorName。

现在我可以在数据表中显示 SponsorName,但是当我添加一条记录时,我得到了以下异常。

[EclipseLink-4002] (Eclipse Persistence Services - 2.2.0.v20110202-r8913):    orgException .eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'SponsorName' in 'field list'
Error Code: 1054

这是我的学习实体类

public class Study implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "StudyId")
private Integer studyId;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 50)
@Column(name = "StudyName")
private String studyName;
@JoinColumn(name = "SponsorId", referencedColumnName = "SponsorId")
@ManyToOne(optional = false)
private Sponsors sponsorId;

@Column(name="SponsorName")
private String sponsorName;

// Constructors getters,setters
}

jsf页面

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"   
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:f="http://java.sun.com/jsf/core"
  xmlns:ui="http://java.sun.com/jsf/facelets"
  xmlns:p="http://primefaces.org/ui">

    <ui:composition template="/SRAtemplate.xhtml">
        <ui:define name="head">
            <title> Study </title>            
        </ui:define>
    <ui:define name="heading">
        Study 
    </ui:define>
    <ui:define name="body">
        <br/>
        <p:growl id="msg" autoUpdate="true"/>
        <br/>
        <h:form id="addstudyform">
            <p:panelGrid columns="2" styleClass="panelgridstyle">

                <f:facet name="header">
                    Add Study
                </f:facet>

                <h:outputLabel for="StudyName" value="StudyName*:"/>
                <p:inputText id="StudyName" value="#studyController.selected.studyName}" maxlength="20" 
                     required="true" requiredMessage="StudyName must be   entered"
                         validatorMessage="StudyName must be an alphanumeric value">
                    <f:validateRegex pattern="[a-zA-Z0-9\s]+"/>
                </p:inputText>

                <h:outputLabel for="Sponsor" value="Sponsor*:"/>
                <p:selectOneMenu id="Sponsor" value="#{studyController.selected.sponsorId}" effect="fade" effectSpeed="0" 
                       required="true" requiredMessage="Sponsor must be selected">  
                    <f:selectItems value="#{sponsorsController.itemsAvailableSelectOne}" var="sponsor" 
                           itemLabel="#{sponsor.sponsorId}" itemValue="#{sponsor}"/>  
                </p:selectOneMenu>

                <p:commandButton id="btnSaveStudy" value="Save" actionListener="#{studyController.createStudy()}"
                                 update=":studyform:studydt"/>
                <p:commandButton id="btnCancelStudy" value="Clear" type="reset" update=":addstudyform"/>

            </p:panelGrid>
        </h:form>
        <br/>
        <br/>
        <h:form id="studyform" style="alignment-adjust:middle">
            <p:dataTable id="studydt" value="#{studyController.retrieveStudy()}" var="item" 
                         paginator="true" rows="15" emptyMessage="No Records Found">

                <p:column filterStyleClass="filterstyle" filterBy="#{item.studyName}"
                          filterMatchMode="startsWith" style="text-align: left;">
                    <f:facet name="header"> StudyName </f:facet>
                    <h:outputText value="#{item.studyName}"/>
                </p:column>

                <p:column filterStyleClass="filterstyle" filterBy="#{item.sponsor}"
                              filterMatchMode="startsWith" style="text-align: center;">
                        <f:facet name="header"> Sponsor </f:facet>
                        <h:outputText value="#{item.sponsorName}"/>
                </p:column>                 

            </p:dataTable>
            </h:form>
    </ui:define>
    </ui:composition>
</html>

这是 perisistence.xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/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_0.xsd">
   <persistence-unit name="ABCPU" transaction-type="JTA">
       <jta-data-source>jdbc/ABC</jta-data-source>
       <exclude-unlisted-classes>false</exclude-unlisted-classes>           
   </persistence-unit>
 <properties>
        <property name="eclipselink.ddl-generation.output-mode" value="database"/>
        <property name="eclipselink.jdbc.batch-writing" value="Buffered"/>
        <property name="eclipselink.logging.level" value="INFO"/>
        <property name="eclipselink.ddl-generation" value="create-or-extend-tables"/>
    </properties>
</persistence>

更新

我认为我收到了错误,因为我在 Study 实体中添加了 SponsorName 列。

我们可以将一个实体的列映射到另一个实体吗?

如果是的话,有人可以建议我怎么做。

4

2 回答 2

2

看来您要做的是按照您希望将事物显示到实体设计中的方式工作,这似乎是个坏主意。当您想以不同的方式显示内容时,您将无法更改整个应用程序。

您不能以您尝试的方式将一个表/实体中的字段映射到另一个表/实体中。您已将您的赞助商实体映射到赞助商表 - StudyName 存在于不同的表中,因此您将始终在读取或写入此实体时遇到异常。以您希望在应用程序中使用它的方式创建实体 - 我认为在 Sponsor java 对象中使用 studyName 或在 study 对象中使用赞助商名称是没有意义的。如果有一个 getSponsorName 检查是否有关联的赞助商并在其上调用 getName,而不是尝试将名称存储在两个位置,难道不是更有意义吗?

如果这是您想要的,有很多选项可以取回字段和/或实体组合。JPQL 可以返回任何东西,例如

"SELECT s.studyId, s.studyName, sp.sponsorName, sp.address FROM Study s left join sp.sponsorId sp"

将返回一个包含字段值的 Object[] 列表。或者

"SELECT s, sp.sponsorName FROM Study s left join sp.sponsorId sp"

返回包含 Study 对象和引用的赞助商名称的 Object[] 列表。

您还可以使用本机查询并使用 ResultSetMappings 映射结果以获得相同的结果。

于 2013-04-23T12:56:25.127 回答
0

我的猜测是这是一个案例问题。尝试将您的 @Column 注释定义为全部大写。

如果你真的想使用驼峰式,那么你需要引用列名,即@Column(name="'StudyName'")。

还有持久性单元属性“eclipselink.jpa.uppercase-column-names”=“true”,它将强制所有列名称为大写。

于 2013-04-09T13:57:40.670 回答