Я использую CRUD-фрейм под названием Tynamo, который, в свою очередь, использует Apache Tapestry и Hibernate. Все это прекрасно работает, за исключением тех случаев, когда я пытаюсь использовать его для CRUD на столе с составным/составным первичным ключом.HibernateEntityValueEncoder NullPointerException
Я решил не ехать по маршруту @EmbeddedId
, так как он не работает вообще с каркасом. При этом я использую метод @IdClass
, который в основном работает; Я думаю, что я - строка или два кода вдали от успеха.
Проблема в том, что когда он начинает использовать отражение для создания объектов, он взрывается и говорит: org.apache.tapestry5.ioc.internal.util.TapestryException
, вызванный java.lang.NullPointerException at org.apache.tapestry5.internal.hibernate.HibernateEntityValueEncoder.<init>(HibernateEntityValueEncoder.java:51)
.
Я честно понятия не имею, в чем заключена сделка, но поскольку у меня есть обычная операция таблицы CRUD, работающая для множества других таблиц, я бы предположил, что это как-то связано с этой таблицей, используя основной/составной первичный ключ.
Одна вещь, которую я пыталась переместить статический внутренний класс в свой собственный пакет, и удалить модификатор класса static
, но произошла точно такая же ошибка.
Вы можете увидеть мой класс ниже:
package com.company.crud.entities;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import com.company.crud.entities.TransferExtension.TransferExtensionPK;
@Entity(name = "Transfer_Extensions")
@IdClass(TransferExtensionPK.class)
public class TransferExtension implements Serializable {
private static final long serialVersionUID = 1L;
@Id
// @NotNull(message = "Please supply a Script Code")
// @Length(min = 3, max = 4)
@Column(name = "Division", nullable = false)
private String scriptCode;
@Id
// @NotNull(message = "Please supply a Transfer Type")
// @Length(min = 3, max = 6)
@Column(name = "Transfer_Type", nullable = false)
private String transferType;
@Column(name = "Extension", nullable = true)
private String englishExtension;
@Column(name = "Span_Extension", nullable = true)
private String spanishExtension;
@Column(name = "Call_Type", nullable = true)
private String callType;
@Column(name = "Call_Center", nullable = true)
private String callCenter;
public TransferExtension() {
}
public TransferExtension(String scriptCode, String transferType,
String englishExtension, String spanishExtension, String callType,
String callCenter) {
this.callCenter = callCenter;
this.callType = callType;
this.englishExtension = englishExtension;
this.scriptCode = scriptCode;
this.spanishExtension = spanishExtension;
this.transferType = transferType;
}
public String getScriptCode() {
return this.scriptCode;
}
public void setScriptCode(String scriptCode) {
this.scriptCode = scriptCode;
}
public String getTransferType() {
return this.transferType;
}
public void setTransferType(String transferType) {
this.transferType = transferType;
}
public String getEnglishExtension() {
return this.englishExtension;
}
public void setEnglishExtension(String englishExtension) {
this.englishExtension = englishExtension;
}
public String getSpanishExtension() {
return this.spanishExtension;
}
public void setSpanishExtension(String spanishExtension) {
this.spanishExtension = spanishExtension;
}
public String getCallType() {
return this.callType;
}
public void setCallType(String callType) {
this.callType = callType;
}
public String getCallCenter() {
return this.callCenter;
}
public void setCallCenter(String callCenter) {
this.callCenter = callCenter;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("TransferExtension [scriptCode=")
.append(this.scriptCode).append(", transferType=")
.append(this.transferType).append(", englishExtension=")
.append(this.englishExtension).append(", spanishExtension=")
.append(this.spanishExtension).append(", callType=")
.append(this.callType).append(", callCenter=")
.append(this.callCenter).append("]");
return builder.toString();
}
public static class TransferExtensionPK implements Serializable {
private static final long serialVersionUID = 4L;
private String scriptCode;
private String transferType;
public TransferExtensionPK() {
}
public TransferExtensionPK(String scriptCode, String transferType) {
this.scriptCode = scriptCode;
this.transferType = transferType;
}
public String getScriptCode() {
return this.scriptCode;
}
public void setScriptCode(String scriptCode) {
this.scriptCode = scriptCode;
}
public String getTransferType() {
return this.transferType;
}
public void setTransferType(String transferType) {
this.transferType = transferType;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("TransferExtensionPK [scriptCode=")
.append(this.scriptCode).append(", transferType=")
.append(this.transferType).append("]");
return builder.toString();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime
* result
+ ((this.scriptCode == null) ? 0 : this.scriptCode
.hashCode());
result = prime
* result
+ ((this.transferType == null) ? 0 : this.transferType
.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof TransferExtensionPK)) {
return false;
}
TransferExtensionPK other = (TransferExtensionPK) obj;
if (this.scriptCode == null) {
if (other.scriptCode != null) {
return false;
}
} else if (!this.scriptCode.equals(other.scriptCode)) {
return false;
}
if (this.transferType == null) {
if (other.transferType != null) {
return false;
}
} else if (!this.transferType.equals(other.transferType)) {
return false;
}
return true;
}
}
}
и стек трассировки:
Hibernate:
select
count(*) as y0_
from
Transfer_Extensions this_
Hibernate:
select
top 25 this_.Division as Division1_0_,
this_.Transfer_Type as Transfer2_1_0_,
this_.Call_Center as Call3_1_0_,
this_.Call_Type as Call4_1_0_,
this_.Extension as Extension1_0_,
this_.Span_Extension as Span6_1_0_
from
Transfer_Extensions this_
[ERROR] pages.List Render queue error in BeginRender[List:pagelink_0]: org.apache.tapestry5.ioc.internal.util.TapestryException
org.apache.tapestry5.ioc.internal.util.TapestryException [at context:List.tml, line 16]
at org.apache.tapestry5.internal.structure.ComponentPageElementImpl$AbstractPhase.invoke(ComponentPageElementImpl.java:158)
at org.apache.tapestry5.internal.structure.ComponentPageElementImpl$BeginRenderPhase.render(ComponentPageElementImpl.java:214)
at org.apache.tapestry5.internal.services.RenderQueueImpl.run(RenderQueueImpl.java:72)
at org.apache.tapestry5.internal.services.PageRenderQueueImpl.render(PageRenderQueueImpl.java:124)
at $PageRenderQueue_11b9cd02019b.render(Unknown Source)
at $PageRenderQueue_11b9cd02019a.render(Unknown Source)
at org.apache.tapestry5.internal.services.MarkupRendererTerminator.renderMarkup(MarkupRendererTerminator.java:37)
at org.apache.tapestry5.services.TapestryModule$31.renderMarkup(TapestryModule.java:1994)
at $MarkupRenderer_11b9cd02019e.renderMarkup(Unknown Source)
at org.apache.tapestry5.services.TapestryModule$30.renderMarkup(TapestryModule.java:1978)
at $MarkupRenderer_11b9cd02019e.renderMarkup(Unknown Source)
at org.apache.tapestry5.services.TapestryModule$29.renderMarkup(TapestryModule.java:1960)
at $MarkupRenderer_11b9cd02019e.renderMarkup(Unknown Source)
at org.apache.tapestry5.services.TapestryModule$28.renderMarkup(TapestryModule.java:1945)
at $MarkupRenderer_11b9cd02019e.renderMarkup(Unknown Source)
at org.apache.tapestry5.services.TapestryModule$27.renderMarkup(TapestryModule.java:1931)
at $MarkupRenderer_11b9cd02019e.renderMarkup(Unknown Source)
at org.apache.tapestry5.services.TapestryModule$26.renderMarkup(TapestryModule.java:1913)
at $MarkupRenderer_11b9cd02019e.renderMarkup(Unknown Source)
at org.apache.tapestry5.services.TapestryModule$25.renderMarkup(TapestryModule.java:1894)
at $MarkupRenderer_11b9cd02019e.renderMarkup(Unknown Source)
at $MarkupRenderer_11b9cd020199.renderMarkup(Unknown Source)
at org.apache.tapestry5.internal.services.PageMarkupRendererImpl.renderPageMarkup(PageMarkupRendererImpl.java:47)
at $PageMarkupRenderer_11b9cd020192.renderPageMarkup(Unknown Source)
at org.apache.tapestry5.internal.services.PageResponseRendererImpl.renderPageResponse(PageResponseRendererImpl.java:67)
at $PageResponseRenderer_11b9cd020194.advised$renderPageResponse_11b9cd020196(Unknown Source)
at $PageResponseRenderer_11b9cd020194$Invocation_renderPageResponse_11b9cd020195.proceedToAdvisedMethod(Unknown Source)
at org.apache.tapestry5.internal.plastic.AbstractMethodInvocation.proceed(AbstractMethodInvocation.java:84)
at org.tynamo.services.TynamoCoreModule$2.advise(TynamoCoreModule.java:353)
at org.apache.tapestry5.internal.plastic.AbstractMethodInvocation.proceed(AbstractMethodInvocation.java:86)
at $PageResponseRenderer_11b9cd020194.renderPageResponse(Unknown Source)
at $PageResponseRenderer_11b9cd020189.renderPageResponse(Unknown Source)
at org.apache.tapestry5.internal.services.PageRenderRequestHandlerImpl.handle(PageRenderRequestHandlerImpl.java:64)
at org.apache.tapestry5.services.TapestryModule$38.handle(TapestryModule.java:2222)
at $PageRenderRequestHandler_11b9cd02018b.handle(Unknown Source)
at $PageRenderRequestHandler_11b9cd020186.handle(Unknown Source)
at org.apache.tapestry5.internal.services.ComponentRequestHandlerTerminator.handlePageRender(ComponentRequestHandlerTerminator.java:48)
at org.apache.tapestry5.services.InitializeActivePageName.handlePageRender(InitializeActivePageName.java:47)
at $ComponentRequestHandler_11b9cd020187.handlePageRender(Unknown Source)
at $ComponentRequestHandler_11b9cd020080.handlePageRender(Unknown Source)
at org.tynamo.routing.services.RouterDispatcher.dispatch(RouterDispatcher.java:26)
at $Dispatcher_11b9cd020084.dispatch(Unknown Source)
at $Dispatcher_11b9cd02007d.dispatch(Unknown Source)
at org.apache.tapestry5.services.TapestryModule$RequestHandlerTerminator.service(TapestryModule.java:302)
at org.apache.tapestry5.internal.services.RequestErrorFilter.service(RequestErrorFilter.java:26)
at $RequestHandler_11b9cd02007e.service(Unknown Source)
at org.apache.tapestry5.services.TapestryModule$3.service(TapestryModule.java:902)
at $RequestHandler_11b9cd02007e.service(Unknown Source)
at org.apache.tapestry5.services.TapestryModule$2.service(TapestryModule.java:892)
at $RequestHandler_11b9cd02007e.service(Unknown Source)
at org.apache.tapestry5.internal.services.StaticFilesFilter.service(StaticFilesFilter.java:90)
at $RequestHandler_11b9cd02007e.service(Unknown Source)
at org.apache.tapestry5.internal.services.CheckForUpdatesFilter$2.invoke(CheckForUpdatesFilter.java:105)
at org.apache.tapestry5.internal.services.CheckForUpdatesFilter$2.invoke(CheckForUpdatesFilter.java:95)
at org.apache.tapestry5.ioc.internal.util.ConcurrentBarrier.withRead(ConcurrentBarrier.java:85)
at org.apache.tapestry5.internal.services.CheckForUpdatesFilter.service(CheckForUpdatesFilter.java:119)
at $RequestHandler_11b9cd02007e.service(Unknown Source)
at $RequestHandler_11b9cd020072.service(Unknown Source)
at org.apache.tapestry5.services.TapestryModule$HttpServletRequestHandlerTerminator.service(TapestryModule.java:253)
at org.apache.tapestry5.internal.gzip.GZipFilter.service(GZipFilter.java:53)
at $HttpServletRequestHandler_11b9cd020074.service(Unknown Source)
at org.apache.tapestry5.upload.internal.services.MultipartServletRequestFilter.service(MultipartServletRequestFilter.java:44)
at $HttpServletRequestHandler_11b9cd020074.service(Unknown Source)
at org.apache.tapestry5.internal.services.IgnoredPathsFilter.service(IgnoredPathsFilter.java:62)
at $HttpServletRequestFilter_11b9cd020070.service(Unknown Source)
at $HttpServletRequestHandler_11b9cd020074.service(Unknown Source)
at org.apache.tapestry5.services.TapestryModule$1.service(TapestryModule.java:852)
at $HttpServletRequestHandler_11b9cd020074.service(Unknown Source)
at $HttpServletRequestHandler_11b9cd02006e.service(Unknown Source)
at org.apache.tapestry5.TapestryFilter.doFilter(TapestryFilter.java:171)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1476)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:501)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:557)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:429)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:255)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:154)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
at org.eclipse.jetty.server.Server.handle(Server.java:370)
at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:494)
at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:971)
at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:1033)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:644)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)
at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:696)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:53)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)
at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.NullPointerException
at org.apache.tapestry5.internal.hibernate.HibernateEntityValueEncoder.<init>(HibernateEntityValueEncoder.java:51)
at org.apache.tapestry5.hibernate.HibernateModule$1.create(HibernateModule.java:103)
at org.apache.tapestry5.internal.services.ValueEncoderSourceImpl.getValueEncoder(ValueEncoderSourceImpl.java:48)
at $ValueEncoderSource_11b9cd0200bf.getValueEncoder(Unknown Source)
at org.apache.tapestry5.internal.services.ContextValueEncoderImpl.toClient(ContextValueEncoderImpl.java:35)
at $ContextValueEncoder_11b9cd0200cd.toClient(Unknown Source)
at org.apache.tapestry5.internal.services.ContextPathEncoderImpl.encodeValue(ContextPathEncoderImpl.java:48)
at org.apache.tapestry5.internal.services.ContextPathEncoderImpl.encodeIntoPath(ContextPathEncoderImpl.java:72)
at $ContextPathEncoder_11b9cd02008f.encodeIntoPath(Unknown Source)
at org.apache.tapestry5.internal.services.ComponentEventLinkEncoderImpl.appendContext(ComponentEventLinkEncoderImpl.java:516)
at org.apache.tapestry5.internal.services.ComponentEventLinkEncoderImpl.createPageRenderLink(ComponentEventLinkEncoderImpl.java:103)
at org.apache.tapestry5.internal.services.linktransform.LinkTransformerInterceptor.createPageRenderLink(LinkTransformerInterceptor.java:50)
at $ComponentEventLinkEncoder_11b9cd020082.createPageRenderLink(Unknown Source)
at org.apache.tapestry5.internal.services.LinkSourceImpl.createPageRenderLink(LinkSourceImpl.java:119)
at $LinkSource_11b9cd0200ce.createPageRenderLink(Unknown Source)
at org.apache.tapestry5.internal.structure.ComponentPageElementResourcesImpl.createPageRenderLink(ComponentPageElementResourcesImpl.java:111)
at org.apache.tapestry5.internal.structure.ComponentPageElementImpl.createPageLink(ComponentPageElementImpl.java:1271)
at org.apache.tapestry5.internal.structure.InternalComponentResourcesImpl.createPageLink(InternalComponentResourcesImpl.java:221)
at org.apache.tapestry5.corelib.components.PageLink.beginRender(PageLink.java:57)
at org.apache.tapestry5.corelib.components.PageLink.beginRender(PageLink.java)
at org.apache.tapestry5.internal.structure.ComponentPageElementImpl$BeginRenderPhase.invokeComponent(ComponentPageElementImpl.java:207)
at org.apache.tapestry5.internal.structure.ComponentPageElementImpl$AbstractPhase.invoke(ComponentPageElementImpl.java:138)
... 94 more
Вот мой ValueEncoder
класс:
import org.apache.tapestry5.ValueEncoder;
import org.apache.tapestry5.services.ValueEncoderFactory;
import com.company.ivr.crud.entities.TransferExtension.TransferExtensionPK;
public class TransferExtensionPKValueEncoder implements
ValueEncoderFactory<TransferExtensionPK>,
ValueEncoder<TransferExtensionPK> {
public ValueEncoder<TransferExtensionPK> create(
Class<TransferExtensionPK> type) {
return this;
}
public String toClient(TransferExtensionPK value) {
return value.getScriptCode() + ":" + value.getTransferType();
}
public TransferExtensionPK toValue(String clientValue) {
String[] values = clientValue.split(":");
return new TransferExtensionPK(values[0], values[1]);
}
}
Вот AppModule
класс:
package com.company.crud.services;
import org.apache.tapestry5.SymbolConstants;
import org.apache.tapestry5.ValueEncoder;
import org.apache.tapestry5.hibernate.HibernateEntityPackageManager;
import org.apache.tapestry5.ioc.Configuration;
import org.apache.tapestry5.ioc.MappedConfiguration;
import org.apache.tapestry5.ioc.ServiceBinder;
import org.apache.tapestry5.ioc.annotations.Contribute;
import org.apache.tapestry5.ioc.services.ApplicationDefaults;
import org.apache.tapestry5.ioc.services.FactoryDefaults;
import org.apache.tapestry5.ioc.services.SymbolProvider;
import org.apache.tapestry5.services.BeanBlockContribution;
import org.apache.tapestry5.services.BeanBlockSource;
import org.apache.tapestry5.services.DisplayBlockContribution;
import org.apache.tapestry5.services.ValueEncoderFactory;
import org.apache.tapestry5.upload.services.UploadSymbols;
import org.tynamo.builder.Builder;
import org.tynamo.builder.BuilderDirector;
import com.company.crud.encoders.TransferExtensionPKValueEncoder;
import com.company.crud.entities.TransferExtension.TransferExtensionPK;
public class AppModule {
/*
* This is the method I've added.
*/
// @Contribute(ValueEncoderSource.class)
public static void contributeValueEncoderSource(
MappedConfiguration<Class<?>, ValueEncoderFactory<?>> config) {
config.addInstance(TransferExtensionPK.class,
TransferExtensionPKValueEncoder.class);
}
public static void bind(ServiceBinder binder) {
}
@Contribute(SymbolProvider.class)
@ApplicationDefaults
public static void provideSymbols(
MappedConfiguration<String, String> configuration) {
configuration.add(SymbolConstants.SUPPORTED_LOCALES, "en, es");
configuration.add(UploadSymbols.REQUESTSIZE_MAX, "2048000");
configuration.add(UploadSymbols.FILESIZE_MAX, "2048000");
}
@Contribute(SymbolProvider.class)
@FactoryDefaults
public static void overrideFactorySymbols(
MappedConfiguration<String, Object> configuration) {
configuration.override(SymbolConstants.APPLICATION_VERSION,
"0.0.1-SNAPSHOT");
}
@Contribute(BeanBlockSource.class)
public static void addCustomBlocks(
Configuration<BeanBlockContribution> configuration) {
configuration.add(new DisplayBlockContribution("boolean",
"blocks/DisplayBlocks", "check"));
configuration.add(new DisplayBlockContribution(
"single-valued-association", "blocks/DisplayBlocks",
"showPageLink"));
configuration.add(new DisplayBlockContribution(
"many-valued-association", "blocks/DisplayBlocks",
"showPageLinks"));
}
@Contribute(HibernateEntityPackageManager.class)
public static void addPackagesToScan(Configuration<String> configuration) {
}
@Contribute(BuilderDirector.class)
public static void addBuilders(
MappedConfiguration<Class<?>, Builder<?>> configuration) {
}
}
я попробовать это в ближайшее время и посмотреть, если это помогает. Совет имеет смысл, тем более, что вы связаны с документом ValueEncoder, который я действительно ценю. И да, я прошел через эту rigmarole с составными ключами и Hibernate до более ранней работы - если у меня есть контроль над дизайном базы данных, я использую тот же подход, что и вы для ключей ...но это не так на этот раз, к сожалению:/ – liltitus27
, поэтому я попытался сделать то, что вы предложили, но я не уверен, что сделал это полностью правильно, в частности метод 'contribValueEncoder(). Я обновил свое оригинальное сообщение, чтобы включить обновленный код и т. д., которые вы рекомендовали мне сделать. можете ли вы предоставить дополнительные предложения для меня, пожалуйста? – liltitus27
Используйте мой код точно. Я не использовал @Contribute (ValueEncoder.class) и вместо этого использовал соглашение об именах. Если вы хотите аннотации, это должен быть @Contribute (ValueEncoderSource.class) –