【发布时间】:2015-11-20 13:05:19
【问题描述】:
我想要一个可以序列化为这样的对象的模型
{
frames = [
[0,1,2,3],
[4,5,4,3],
[2,1,0]
]
}
现在我不知道该怎么做,所以我这样做了
* Created by michael on 26/08/15.
*/
@Entity
public class Frame {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
public Frame(List<Integer> data) {
this.data = data;
}
public Frame() {}
public List<Integer> getData() {
return data;
}
public void setData(List<Integer> data) {
this.data = data;
}
@ElementCollection
@NotNull
List<Integer> data;
}
@Entity
public class DacChannel {
@Id
private int number;
@OneToMany(cascade = CascadeType.ALL)
@NotNull
private List<Frame> frames;
public DacChannel(int number, List<Frame> frames) {
setNumber(number);
setFrames(frames);
}
public DacChannel() {
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public List<Frame> getFrames() {
return frames;
}
public void setFrames(List<Frame> frames) {
this.frames = frames;
}
}
但它也不能正常工作。我可以通过发布请求创建此实体
{
"number": 0,
"frames": [
{"data": [1,2,3]},
{"data": [3,4,5]}
]
}
但不知何故
{
"number": 1,
"frames": [
{"data": [1,2,3]},
{"data": [3,4,5]}
]
}
给我一个错误。
nested exception is javax.validation.ConstraintViolationException: Validation failed for classes [demo.model.board.DacChannel] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
ConstraintViolationImpl{interpolatedMessage='may not be null', propertyPath=frames, rootBeanClass=class demo.model.board.DacChannel, messageTemplate='{javax.validation.constraints.NotNull.message}'}
]] with root cause
javax.validation.ConstraintViolationException: Validation failed for classes [demo.model.board.DacChannel] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
ConstraintViolationImpl{interpolatedMessage='may not be null', propertyPath=frames, rootBeanClass=class demo.model.board.DacChannel, messageTemplate='{javax.validation.constraints.NotNull.message}'}
]
at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:160)
at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreInsert(BeanValidationEventListener.java:95)
at org.hibernate.action.internal.EntityInsertAction.preInsert(EntityInsertAction.java:218)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:97)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:465)
at org.hibernate.engine.spi.ActionQueue.executeInserts(ActionQueue.java:337)
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:176)
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:216)
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:334)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:289)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:195)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:126)
at org.hibernate.jpa.event.internal.core.JpaMergeEventListener.saveWithGeneratedId(JpaMergeEventListener.java:73)
at org.hibernate.event.internal.DefaultMergeEventListener.saveTransientEntity(DefaultMergeEventListener.java:271)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:251)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:189)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:886)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:868)
at org.hibernate.engine.spi.CascadingActions$6.cascade(CascadingActions.java:277)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:350)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:293)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)
at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:379)
at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:319)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:296)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:118)
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:470)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:255)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:317)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:186)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:85)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:876)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:858)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:863)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:1196)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
所以我想“你在说什么 null,我已经在请求正文中包含了所有属性!”。我不明白发生了什么。
另外,我可以用 jpa 做我最初想做的事情吗?也许使用@Lob 之类的?或者也许我可以用 mongodb 轻松做到这一点?我现在使用 postres 和 h2(用于测试)。
编辑1
经过一些实验,我发现在此处删除 NotNull 注释后,一切正常。不过,我的问题是保持不变。我可以做我最初想做的事情(使用 mongodb 或 @Lob 吗?)。我得到这个错误的原因是什么?我不想删除 NonNull 注释。
@ElementCollection 列出数据;
【问题讨论】:
-
JPA 与此类异常无关(除了您的 JPA 提供者移交处理)。它是“Bean 验证”。 JSON 的东西没有输入到 JPA,所以没什么兴趣
-
@NeilStockton 是的,好的。不是很有帮助,抱歉。
-
请分享抛出此异常的代码块。帧无法从 json 正确映射到您的对象。
-
所以消息说“DacChannel”有一个不应该存在的空值。看看那个类,只有一个地方可以是……“框架”。那为什么它是空的呢?
-
@İlkerKorkut 没有引发此异常的代码。这是一个弹簧数据休息。都是自动的。
标签: java spring jpa spring-data-rest