我正在尝试使用特定映射更新实体:
@Entity
@Table(name = "obs_structure2")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Structure implements Serializable{
private String id;
private String tag;
private String description;
private Set<Version> parentVersions = new HashSet<>();
private List<StructureElement> children = new ArrayList<>();
private List<StructureElement> slaves = new ArrayList<>();
private PersistenceSignature signature = new PersistenceSignature();
@OneToMany(mappedBy = "parentStructure")
public List<StructureElement> getChildren() {
return children;
}
public void addChild(StructureElement se)
{
if(this.children.contains(se))
{
this.children.add(se);
}
}
和
@Entity
@Table(name = "obs_structure_element2")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class StructureElement implements Serializable{
private long id;
private String tag;
private String description;
private boolean repetitive = false;
private boolean optional = false;
private Integer position = 1;
private Structure parentStructure;
private Structure typeStructure;
private PersistenceSignature signature = new PersistenceSignature();
@ManyToOne
@JoinColumn(name = "parent_id")
@JsonIgnore
public Structure getParentStructure() {
return parentStructure;
}
这是我的控制者:
@PutMapping("/update")
public StructureElement update(@RequestBody StructureElement se){
logger.info("Call to StructureElementController.update with se = " + se);
this.connectToDatabase();
StructureElement updatedSE;
try{
boolean exists = this.repository.exists(se.getId());
if(!exists){
logger.error("Could not find StructureElement to update. se = " + se);
return null;
}
updatedSE = this.repository.save(se);
logger.info("Updated SE = " + updatedSE);
}catch (Exception e){
logger.error("Could not update structure element. se = " + se, e);
return null;
}
return updatedSE;
}
当我尝试更新元素时,parentStructure
被覆盖为空。
如果我删除了@JsonIgnore
注释,我收到此StackOverflow
错误:
[ERROR] 2018-01-03 14:22:38.577 [http-nio-8080-exec-5] o.a.c.c.C.[.[.[.[dispatcherServlet] 181 - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.StackOverflowError] with root cause
java.lang.StackOverflowError: null
at java.util.AbstractCollection.toString(AbstractCollection.java:454) ~[?:1.8.0_151]
at java.lang.String.valueOf(String.java:2994) ~[?:1.8.0_151]
at java.lang.StringBuilder.append(StringBuilder.java:131) ~[?:1.8.0_151]
at be.groups.observatory.server.model.Structure.toString(Structure.java:147) ~[classes/:?]
at java.lang.String.valueOf(String.java:2994) ~[?:1.8.0_151]
at java.lang.StringBuilder.append(StringBuilder.java:131) ~[?:1.8.0_151]
at be.groups.observatory.server.model.StructureElement.toString(StructureElement.java:116) ~[classes/:?]
at java.lang.String.valueOf(String.java:2994) ~[?:1.8.0_151]
at java.lang.StringBuilder.append(StringBuilder.java:131) ~[?:1.8.0_151]
at java.util.AbstractCollection.toString(AbstractCollection.java:462) ~[?:1.8.0_151]
at java.lang.String.valueOf(String.java:2994) ~[?:1.8.0_151]
at java.lang.StringBuilder.append(StringBuilder.java:131) ~[?:1.8.0_151]
at be.groups.observatory.server.model.Structure.toString(Structure.java:147) ~[classes/:?]
at java.lang.String.valueOf(String.java:2994) ~[?:1.8.0_151]
at java.lang.StringBuilder.append(StringBuilder.java:131) ~[?:1.8.0_151]
at be.groups.observatory.server.model.StructureElement.toString(StructureElement.java:116) ~[classes/:?]
at java.lang.String.valueOf(String.java:2994) ~[?:1.8.0_151]
at java.lang.StringBuilder.append(StringBuilder.java:131) ~[?:1.8.0_151]
at java.util.AbstractCollection.toString(AbstractCollection.java:462) ~[?:1.8.0_151]
at java.lang.String.valueOf(String.java:2994) ~[?:1.8.0_151]
at java.lang.StringBuilder.append(StringBuilder.java:131) ~[?:1.8.0_151]
at be.groups.observatory.server.model.Structure.toString(Structure.java:147) ~[classes/:?]
对于那些知道vue.js
的人来说,这是我的组成部分:
<template>
<div class="t-body">
<obs-sidebar></obs-sidebar>
<main class="t-content">
<div v-if="updated" class="c-notification c-notification--success" role="dialog" aria-label="first notification" aria-describedby="desc_1">
<p id="desc_1" class="c-notification__message">L'élément de structure à bien été mise à jour.</p>
</div>
<div v-if="errors && errors.length">
<div v-for="error of errors" class="c-notification c-notification--danger">
{{ error.message }}
</div>
</div>
<div class="l-row l-row--gutter">
<div class="l-col">
<h1>{{ msg }} - {{ element_id }}</h1>
</div>
</div>
<loader v-if="visible"></loader>
<div class="l-row l-row--gutter" v-else>
<div class="l-col-4">
<form class="c-form full-width" @submit.prevent="updateStructureElement">
<div class="l-row">
<fieldset class="c-form__fieldset">
<legend class="c-form__legend">Remplissez le formulaire</legend>
<div class="l-row nice-top">
<div class="l-col-3 l-justify--end nice-right">
<div class="c-form__field-group">
<label for="tag" class="c-form__label">Tag <span class="s-text s-text--danger">* </span></label>
</div>
</div>
<div class="l-col-7">
<div class="c-form__field-group full-width">
<input id="tag" class="c-form__field full-width" type="text" name="tag" v-model="element.tag"/>
</div>
</div>
</div>
<div class="l-row nice-top">
<div class="l-col-3 l-justify--end nice-right">
<div class="c-form__field-group">
<label for="description" class="c-form__label">Description <span class="s-text s-text--danger">* </span></label>
</div>
</div>
<div class="l-col-7">
<div class="c-form__field-group full-width">
<textarea id="description" class="c-form__field minimal-h" name="description" v-model="element.description"></textarea>
</div>
</div>
</div>
<div class="l-row nice-top">
<div class="l-col-6 l-justify--end nice-right">
<div class="c-form__field-group">
<label for="optional" class="c-form__label">Optional <span class="s-text s-text--danger">* </span></label>
</div>
</div>
<div class="l-col-6">
<div class="c-form__field-group">
<input id="optional" class="c-form__field" type="checkbox" name="optional" v-model="element.optional"/>
</div>
</div>
</div>
<div class="l-row nice-top">
<div class="l-col-6 l-justify--end nice-right">
<div class="c-form__field-group">
<label for="repetitive" class="c-form__label">Répétitif <span class="s-text s-text--danger">* </span></label>
</div>
</div>
<div class="l-col-6">
<div class="c-form__field-group full-width">
<input id="repetitive" class="c-form__field" type="checkbox" name="repetitive" v-model="element.repetitive"/>
</div>
</div>
</div>
</fieldset>
</div>
<div class="l-row nice-top">
<div class="l-col-offset-3 l-col-7">
<button class="c-btn c-btn--primary c-btn--raised c-btn--ripple c-form__button full-width s-text--center" type="submit">Soumettre</button>
</div>
</div>
</form>
</div>
</div>
</main>
</div>
</template>
<script>
import Loader from 'gso-loader';
import {state, show, hide} from 'gso-loader/store';
import {HTTP} from '../http-common';
import ObsSidebar from './parts/sidebar.vue';
export default{
name: 'update-structure-element',
props: ['element_id'],
data() {
return {
msg: 'Mise à jour de l\'élément',
element: [],
errors: [],
updated: false
};
},
computed: {
visible() {
return state.visible;
}
},
methods: {
updateStructureElement: function () {
let seToUpdate = this.element;
console.log('To update = ' + JSON.stringify(seToUpdate));
HTTP.put('structure-element/update', seToUpdate, {headers: {'Content-Type': 'application/json'}})
.then(response => {
console.log('response = ' + response);
this.element = response.data;
this.updated = true;
})
.catch(e => {
console.log('Error = ' + e);
this.errors.push(e);
});
}
},
components: {ObsSidebar, Loader},
created() {
show();
let elementId = this.$route.params.element_id;
HTTP.get('structure-element/' + elementId)
.then(response => {
this.element = response.data;
hide();
})
.catch(e => {
this.errors.push(e);
hide();
});
}
};
</script>
答案 0 :(得分:0)
好吧,我正在查看一些文章,并改变了我更新实体的方式:
@PutMapping("/update")
public StructureElement update(@RequestBody StructureElement se){
StructureElement databaseElement;
logger.info("Call to StructureElementController.update with se = " + se);
this.connectToDatabase();
try{
databaseElement = this.repository.findOne(se.getId());
if(databaseElement == null){
logger.error("Could not find StructureElement to update. se = " + se);
return null;
}
// Update
databaseElement.setDescription(se.getDescription());
databaseElement.setTag(se.getTag());
databaseElement.setOptional(se.isOptional());
databaseElement.setRepetitive(se.isRepetitive());
databaseElement.getSignature().setModificationDate(new Date());
databaseElement = this.repository.save(databaseElement);
logger.info("Updated SE = " + databaseElement);
}catch (Exception e){
logger.error("Could not update structure element. se = " + se, e);
return null;
}
return databaseElement;
}
现在这个有效。
似乎Spring数据JPA不想像简单的JPA EntityManager
那样更新实体....