我有一个项目需要设置与JAVA-EE项目一起使用的SMS网关。 GAMMU 1.36.0被选中。
后端DB是Postgresql 9.4,创建了表收件箱和序列来保存来自SMS。
使用创建的收件箱:
CREATE TABLE inbox (
"UpdatedInDB" timestamp(0) WITHOUT time zone NOT NULL DEFAULT LOCALTIMESTAMP(0),
"ReceivingDateTime" timestamp(0) WITHOUT time zone NOT NULL DEFAULT LOCALTIMESTAMP(0),
"Text" text NOT NULL,
"SenderNumber" varchar(20) NOT NULL DEFAULT '',
"Coding" varchar(255) NOT NULL DEFAULT 'Default_No_Compression',
"UDH" text NOT NULL,
"SMSCNumber" varchar(20) NOT NULL DEFAULT '',
"Class" integer NOT NULL DEFAULT '-1',
"TextDecoded" text NOT NULL DEFAULT '',
"ID" serial PRIMARY KEY,
"RecipientID" text NOT NULL,
"Processed" boolean NOT NULL DEFAULT 'false',
CHECK ("Coding" IN
('Default_No_Compression','Unicode_No_Compression','8bit','Default_Compression','Unicode_Compression')));
id是序列号保存在:
--CREATE SEQUENCE inbox_ID_seq;
表结构如下:
smsd-> \d inbox
Table "public.inbox"
Column | Type | Modifiers
-------------------+--------------------------------+----------------------------------------------------------------
UpdatedInDB | timestamp(0) without time zone | not null default ('now'::text)::timestamp(0) without time zone
ReceivingDateTime | timestamp(0) without time zone | not null default ('now'::text)::timestamp(0) without time zone
Text | text | not null
SenderNumber | character varying(20) | not null default ''::character varying
Coding | character varying(255) | not null default 'Default_No_Compression'::character varying
UDH | text | not null
SMSCNumber | character varying(20) | not null default ''::character varying
Class | integer | not null default (-1)
TextDecoded | text | not null default ''::text
ID | integer | not null default nextval('"inbox_ID_seq"'::regclass)
RecipientID | text | not null
Processed | boolean | not null default false
Indexes:
"inbox_pkey" PRIMARY KEY, btree ("ID")
Check constraints:
"inbox_Coding_check" CHECK ("Coding"::text = ANY (ARRAY['Default_No_Compression'::character varying, 'Unicode_No_Compression'::character varying, '8bit'::character varying, 'Default_Compression'::character varying, 'Unicode_Compression'::character varying]::text[]))
Triggers:
update_timestamp BEFORE UPDATE ON inbox FOR EACH ROW EXECUTE PROCEDURE update_timestamp()
smsd->
请注意:列ids'表中的位置是10。
此表与GAMMU 1.36.0配合使用,可以正确发送和接收短信。
当我尝试开发EJB以将收件箱信息带到我的Web应用程序时。
我使用的是JPA 2.1,实现是EclipseLink 2.5.2。 persistence.xml看起来像:
<persistence-unit name="SmsdJPANBPU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<mapping-file>com/longz/smsd/model/SmsdInboxEntity.xml</mapping-file>
<mapping-file>com/longz/smsd/model/SmsdOutboxEntity.xml</mapping-file>
<mapping-file>com/longz/smsd/model/SmsdSentitemsEntity.xml</mapping-file>
<class>com.longz.smsd.model.SmsdInboxEntity</class>
<class>com.longz.smsd.model.SmsdOutboxEntity</class>
<class>com.longz.smsd.model.SmsdSentitemsEntity</class>
<properties>
<property name="eclipselink.jdbc.url" value="jdbc:postgresql://10.0.1.100:5433/smsd"/>
<property name="eclipselink.jdbc.driver" value="org.postgresql.Driver"/>
<property name="eclipselink.jdbc.user" value="any"/>
<property name="eclipselink.jdbc.password" value="any"/>
<property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
</properties>
</persistence-unit>
JPA实体bean定义:
@Entity
@Table(name = "inbox", schema = "public", catalog = "smsd")
@NamedQueries({
/*@NamedQuery(name = "Inbox.findAll", query = "SELECT i FROM InboxEntity i ORDER BY i.id DESC"),*/
@NamedQuery(name = "Inbox.findAll", query = "SELECT i FROM SmsdInboxEntity i order by i.id desc"),
......
public class SmsdInboxEntity implements Serializable{
......
@Id
@SequenceGenerator(name="JOB_MISFIRE_ID_GENERATOR", sequenceName="inbox_ID_seq",schema = "public", allocationSize=1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="JOB_MISFIRE_ID_GENERATOR")
@Column(name = "ID", nullable = false, insertable = true, updatable = true)
public int getId() {
return id;
}
......
}
无状态会话bean:
@Remote(InboxEntityFacadeRemote.class)
@Stateless(mappedName= "inboxEntityFacadeEJB")
public class InboxEntityFacade extends AbstractFacade<SmsdInboxEntity> implements InboxEntityFacadeRemote {
@PersistenceContext(unitName = "SmsdJPANBPU")
private EntityManager em;
@Override
protected EntityManager getEntityManager() {
return em;
}
public InboxEntityFacade() {
super(SmsdInboxEntity.class);
}
@Override
public List<SmsdInboxEntity> findAll(){
Query query = em.createNamedQuery("Inbox.findAll");
return new LinkedList<SmsdInboxEntity>(query.getResultList());
/*return super.findAll();*/
}
我尝试使用findall()函数列出收件箱中的所有短信。此函数将调用命名查询语句:
@NamedQuery(name = "Inbox.findAll", query = "SELECT i FROM SmsdInboxEntity i order by i.id desc"),
将EJB客户端测试为:
try {
Context context = new InitialContext(properties);
InboxEntityFacadeRemote inboxEnFaRemote = (InboxEntityFacadeRemote)context.lookup("inboxEntityFacadeEJB#com.longz.smsd.remote.InboxEntityFacadeRemote");
System.out.println("inboxEntityFacadeEJB found.");
List<com.longz.smsd.model.SmsdInboxEntity> todaysemails = inboxEnFaRemote.findAll();
System.out.println("Records found: "+ todaysemails.size());
todaysemails.stream().forEach((e) -> {
System.out.println(e.getTextDecoded());
});
}catch (NamingException e) {
e.printStackTrace();
}
}
到目前为止,一切都很好。但抛出非常奇怪的错误:
run:
inboxEntityFacadeEJB found.
Exception in thread "main" javax.ejb.EJBException: EJB Exception: ; nested exception is:
javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: column "id" does not exist
Position: 8
Error Code: 0
Call: SELECT ID, Class, Coding, Processed, ReceivingDateTime, RecipientID, SenderNumber, SMSCNumber, Text, TextDecoded, UDH, UpdatedInDB FROM smsd.public.inbox ORDER BY ID DESC
Query: ReadAllQuery(name="Inbox.findAll" referenceClass=SmsdInboxEntity sql="SELECT ID, Class, Coding, Processed, ReceivingDateTime, RecipientID, SenderNumber, SMSCNumber, Text, TextDecoded, UDH, UpdatedInDB FROM smsd.public.inbox ORDER BY ID DESC")
at weblogic.ejb.container.internal.RemoteBusinessIntfProxy.unwrapRemoteException(RemoteBusinessIntfProxy.java:117)
at weblogic.ejb.container.internal.RemoteBusinessIntfProxy.invoke(RemoteBusinessIntfProxy.java:92)
at com.sun.proxy.$Proxy0.findAll(Unknown Source)
at weblogicejbclient.WeblogicInboxEJBClient.main(WeblogicInboxEJBClient.java:38)
Caused by: javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: column "id" does not exist
Position: 8
Error Code: 0
Call: SELECT ID, Class, Coding, Processed, ReceivingDateTime, RecipientID, SenderNumber, SMSCNumber, Text, TextDecoded, UDH, UpdatedInDB FROM smsd.public.inbox ORDER BY ID DESC
Query: ReadAllQuery(name="Inbox.findAll" referenceClass=SmsdInboxEntity sql="SELECT ID, Class, Coding, Processed, ReceivingDateTime, RecipientID, SenderNumber, SMSCNumber, Text, TextDecoded, UDH, UpdatedInDB FROM smsd.public.inbox ORDER BY ID DESC")
at org.eclipse.persistence.internal.jpa.QueryImpl.getDetailedException(QueryImpl.java:378)
at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:260)
at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:469)
at com.longz.smsd.ejb.InboxEntityFacade.findAll(InboxEntityFacade.java:36)
at com.longz.smsd.ejb.InboxEntityFacadeEJB_s9wt3_InboxEntityFacadeRemoteImpl.__WL_invoke(Unknown Source)
at weblogic.ejb.container.internal.SessionRemoteMethodInvoker.invoke(SessionRemoteMethodInvoker.java:34)
at com.longz.smsd.ejb.InboxEntityFacadeEJB_s9wt3_InboxEntityFacadeRemoteImpl.findAll(Unknown Source)
at com.longz.smsd.ejb.InboxEntityFacadeEJB_s9wt3_InboxEntityFacadeRemoteImpl_WLSkel.invoke(Unknown Source)
at weblogic.rmi.internal.BasicServerRef.invoke(BasicServerRef.java:701)
at weblogic.rmi.cluster.ClusterableServerRef.invoke(ClusterableServerRef.java:231)
at weblogic.rmi.internal.BasicServerRef$1.run(BasicServerRef.java:527)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:146)
at weblogic.rmi.internal.BasicServerRef.handleRequest(BasicServerRef.java:523)
at weblogic.rmi.internal.wls.WLSExecuteRequest.run(WLSExecuteRequest.java:118)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:311)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:263)
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: column "id" does not exist
Position: 8
Error Code: 0
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:340)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:682)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:558)
at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:2002)
at org.eclipse.persistence.sessions.server.ServerSession.executeCall(ServerSession.java:570)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:242)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeSelectCall(DatasourceCallQueryMechanism.java:299)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.selectAllRows(DatasourceCallQueryMechanism.java:694)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectAllRowsFromTable(ExpressionQueryMechanism.java:2738)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectAllRows(ExpressionQueryMechanism.java:2691)
at org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:495)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1168)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:899)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1127)
at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:403)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1215)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2896)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1804)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1786)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1751)
at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:258)
... 15 more
Caused by: org.postgresql.util.PSQLException: ERROR: column "id" does not exist
Position: 8
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2198)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1927)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:561)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:419)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:304)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeSelect(DatabaseAccessor.java:1007)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:642)
... 35 more
Java Result: 1
BUILD SUCCESSFUL (total time: 1 second)
似乎PSQL正在尝试查找&#34; id&#34;列位置8而不是位置10,实际上是#34; id&#34;列位于收件箱表中的第10位。
请提出任何想法和建议!理解!!
答案 0 :(得分:0)
您的问题区分大小写:JPA works in case insensitive mode默认情况下(即它不会在其查询中引用标识符),而PostgreSQL will convert any unquoted identifiers to lower-case(这是PostgreSQL尝试实现不区分大小写的方式) 。但是,您在区分大小写模式下定义了"ID"
列(请注意引号)。
一个丑陋的解决方法是,您以区分大小写的方式定义您的实体:
@Column(name = "\"ID\"")
或者,您可以以不区分大小写的方式定义表(首选):
CREATE TABLE inbox (
ID serial PRIMARY KEY
-- ...
);
答案 1 :(得分:0)
最后。通过使用本机SQL查询
修复了此问题Query query = em.createNativeQuery("Select * from inbox",com.longz.smsd.model.SmsdInboxEntity.class);
return new LinkedList<SmsdInboxEntity>(query.getResultList());
似乎JSQL在这种情况下不是100%有效。
这个将帮助其他有同样问题的人。