Исходя из того, что я понял, вот один из способов сделать это
select c.id customer_id, c.sur, c.fam, h.id horoscope_id, h.sur h_sur,
h.fam h_fam, h.horoscope
FROM customer c join horoscope h
on (c.sur = h.sur and c.fam = h.fam)
or (h.sur is null and c.fam = h.fam and not exists
(select 1 from horoscope h1 where h1.sur = c.sur and h1.fam = c.fam)
)
и результат
Один из основных недостатков использования Spring MVC + hibernate заключается в том, что естественным подходом является использование объекта домена hibernate в качестве объекта поддержки формы. Spring свяжет что-либо в запросе на основе имени DEFAULT. Это непреднамеренно включает такие вещи, как идентификатор или имя (обычно первичный ключ) или другие устанавливаемые свойства спящего режима. Это также делает вас уязвимыми для внедрения формы.
Чтобы быть в безопасности в этом сценарии, вы должны использовать что-то вроде:
protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder)
throws Exception {
String[] allowedFields = {"name", "birthday"}
binder.setAllowedFields(allowedFields);
}
и ЯВНО установите РАЗРЕШЕННЫЕ поля только на те, которые находятся в вашей форме, и исключите первичный ключ, иначе вы будете кончится беспорядком !!!
Ваша проблема может быть связана с Отделенными объектами. Поскольку Ваш ДАО был изменен вне Быть в спящем режиме сессии, необходимо повторно прикрепить объект к Быть в спящем режиме сессии перед сохранением. Можно сделать это любой путем явного обеспечения объекта в сессию прежде, чем сохранить Слияние использования () или обновление (). Эксперимент с обоими, и прочитал документацию для тех действий, поскольку они имеют различные эффекты в зависимости от структуры Ваших объектов данных.
Для ответа на непосредственный вопрос проблема, с которой Вы имеете, в спящем режиме, имеет отношение к следующей последовательности событий:
formBackingObject
formBackingObject
formBackingObject
doSubmitAction
назван, тот же экземпляр Thingie
поддержка объекта передается как командаБудьте в спящем режиме ничего не знает о сессии в этой точке, потому что она закрывается, таким образом, Вы получаете ошибку. Хорошие новости - то, что Вы не должны делать его тот путь, и корректный путь обойдет ту ошибку полностью.
formBackingObject
метод используется для заполнения объекта команды формы с данными до показа формы. На основе Вашего обновленного вопроса это кажется, что Вы просто пытаетесь отобразить форму, заполненную с информацией от данной строки базы данных и обновить ту строку базы данных, когда форма отправлена.
Похоже, что у Вас уже есть образцовый класс для Вашей записи; я назову это Record
класс в этом ответе). У Вас также есть ДАО для Record
класс, который я назову RecordDao
. Наконец, Вам нужен a UpdateRecordCommand
класс, который будет Вашим объектом поддержки. UpdateRecordCommand
должен быть определен со следующими полями и методами set/методами считывания:
public class UpdateRecordCommand {
// Row ID of the record we want to update
private int rowId;
// New name
private int String name;
// New scheme
private int String scheme;
// New URL
private int String url;
// New enabled flag
private int boolean enabled;
// Getters and setters left out for brevity
}
Затем определите свою форму с помощью следующего кода:
<form:form commandName="update">
<span>Name:</span>
<span><form:input path="name" /></span><br/>
<span>Scheme:</span>
<span><form:input path="scheme" /></span><br/>
<span>Url:</span>
<span><form:input path="url" /></span><br/>
<span>Enabled:</span>
<span><form:checkbox path="enabled"/></span><br/>
<form:hidden path="rowId"/>
<input type="submit" value="Save Changes" />
</form:form>
Теперь Вы определяете свой контроллер формы, который заполнит форму в formBackingObject
и обработайте запрос обновления в doSubmitAction
.
public class UpdateRecordController extends SimpleFormController {
private RecordDao recordDao;
// Setter and getter for recordDao left out for brevity
public UpdateRecordController() {
setCommandClass(UpdateRecordCommand.class);
setCommandName("update");
}
@Override
protected Object formBackingObject(HttpServletRequest request)
throws Exception {
// Use one of Spring's utility classes to cleanly fetch the rowId
int rowId = ServletRequestUtils.getIntParameter(request, "rowId");
// Load the record based on the rowId paramrter, using your DAO
Record record = recordDao.load(rowId);
// Populate the update command with information from the record
UpdateRecordCommand command = new UpdateRecordCommand();
command.setRowId(rowId);
command.setName(record.getName());
command.setScheme(record.getScheme());
command.setUrl(record.getUrl());
command.setEnabled(record.getEnabled());
// Returning this will pre-populate the form fields
return command;
}
@Override
protected void doSubmitAction(Object command) throws Exception {
// Load the record based on the rowId in the update command
UpdateRecordCommand update = (UpdateRecordCommand) command;
Record record = recordDao.load(update.getRowId());
// Update the object we loaded from the data store
record.setName(update.getName());
record.setScheme(update.getScheme());
record.setUrl(update.getUrl());
record.setEnabled(update.setEnaled());
// Finally, persist the data using the DAO
recordDao.save(record);
}
}
Что продолжалось, который является? name=rowId так или иначе портил сообщение формы. После того как я изменил это на имя, которое не отразило параметр в объекте, все хорошо работало. Никакое изменение в ДАО или необходимом коде контроллера.
Благодаря всем для Ваших ответов. Это помогло мне сузить то, что продолжалось.