如何在JPA + REST中设置外键

时间:2015-12-23 04:24:29

标签: java jpa

我有以下JPA实体

my JPA entity :: BookForUser 
@Id
private int id;

@ManyToOne
@JoinColumn(name="e_mail")
private User user;// I do not want User object in the table, 
//I want a string e_mail to be foreign key in my entity table

var booking = { e_mail: localStorage.getItem("email"),...

上面是我的JSON代码,用于填充JS中的bookForUser对象。我正在使用JAVA + REST作为后端。但在成功路由REST调用之后 我得到了一个例外

  

SEVERE:servlet [com.RRS.config.RRSConfig]的Servlet.service()在路径[/ RRS_2]的上下文中引发了异常org.glassfish.jersey.server.ContainerException:com.fasterxml.jackson.databind.exc .UnrecognizedPropertyException:无法识别的字段" e_mail"在[来源:org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@178546ce; line:1,column:12](通过引用链:com.RRS.bean.Reservation [" e_mail"])]与根本原因com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:无法识别的字段& #34;的E_mail" (class clasName),未在[来源:org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@178546ce;中标记为可忽略;在com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:51)的com.fasterxml.jackson.databind.DeserializationContext.reportUnknownProperty(DeserializationContext.java:839)中的行:1,列:12]       在com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1045)       在com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1352)       在com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1330)       在com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:264)       在com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:125)       at com.fasterxml.jackson.databind.ObjectReader._bind(ObjectReader.java:1470)       at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:912)       在com.fasterxml.jackson.jaxrs.base.ProviderBase.readFrom(ProviderBase.java:811)       at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor $ TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:256)       at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor $ TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:235)       在org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:155)       at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundReadFrom(MappableExceptionWrapperInterceptor.java:74)       在org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:155)       在org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1085)       at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:874)       在org.glassfish.jersey.server.ContainerRequest.readEntity(ContainerRequest.java:271)       at org.glassfish.jersey.server.internal.inject.EntityParamValueFactoryProvider $ EntityValueFactory.provide(EntityParamValueFactoryProvider.java:96)       在org.glassfish.jersey.server.spi.internal.ParamValueFactoryWithSource.provide(ParamValueFactoryWithSource.java:71)       在org.glassfish.jersey.server.spi.internal.ParameterValueHelper.getParameterValues(ParameterValueHelper.java:94)       at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider $ AbstractMethodParamInvoker.getParamValues(JavaResourceMethodDispatcherProvider.java:127)       at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider $ TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:205)       at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99)       在org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389)       在org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347)       在org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)       在org.glassfish.jersey.server.ServerRuntime $ 2.run(ServerRuntime.java:326)       在org.glassfish.jersey.internal.Errors $ 1.call(Errors.java:271)       在org.glassfish.jersey.internal.Errors $ 1.call(Errors.java:267)       在org.glassfish.jersey.internal.Errors.process(Errors.java:315)       在org.glassfish.jersey.internal.Errors.process(Errors.java:297)       在org.glassfish.jersey.internal.Errors.process(Errors.java:267)       在org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)       在org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)       在org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)       在org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:471)       在org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:425)       在org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:383)       在org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:336)       在org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:223)       在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)       在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)       在org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)       在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)       在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)       在org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)       在org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)       在org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)       at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)       在org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)       在org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)       在org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)       在org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)       在org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)       at org.apache.coyote.AbstractProtocol $ AbstractConnectionHandler.process(AbstractProtocol.java:611)       at org.apache.tomcat.util.net.JIoEndpoint $ SocketProcessor.run(JIoEndpoint.java:314)       在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)       at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:615)       at org.apache.tomcat.util.threads.TaskThread $ WrappingRunnable.run(TaskThread.java:61)       在java.lang.Thread.run(Thread.java:745)

e_mail是实体用户的主键。表名与类名用户相同 由于String电子邮件不是保留主键的好方法,我计划将其更改为int userId。但问题仍然存在。

我想要的是

class User : primary key=email, some other params
class BookForUser : primary key = id, some other params, foreign key = email

我所理解的是BookForUser没有完整的User对象。我不想要它。

这种声明外键是否正确? (我想要1个用户=许多预订)

如何将此电子邮件属性传递给我的Java代码?

1 个答案:

答案 0 :(得分:0)

首先,将电子邮件地址等字符串作为主要内容并不是一个好主意。你可以拥有的是:

将用户的主键设为整数,并为电子邮件设置一个唯一的字段。这允许您使用整数主键(更易于使用和引用)并避免重复电子邮件地址。

另一种方法是为用户创建一个类,为图书创建一个类。 目前这些不同,它们之间没有联系。然后,您将有第三个类使用 UserReservedBooks

中的主键连接它们

示例:Class UserReservedBooks {idReservation(此类的主键),idUser - >用户的主键idBook - >本书的主键,...特定于预约的其他参数,例如保留的日期等。)

这种方法的优点是:

  1. 1用户可以进行多次预约
  2. 它允许您(如果您愿意)查看哪些用户保留了特定图书
  3. 您还可以让用户一次预订多本图书。
  4. 这本书可以由多人保留。
  5. 您的用户将拥有唯一的电子邮件地址
  6. 您可以避免重复图书。