Я начинаю с SQL-заявления. У меня есть этот sql (см. Ниже), когда я тестирую его, он хорошо работает в SQL Management Studio. Я получаю ожидаемые результаты.
select distinct p.id, p.name, m.name
from test001.npd.projects p,
test001.npd.customer,
test001.npd.manager w
where lower(p.name) like '%%' and lower(p.customer) like '%%' and lower(m.name) like '%k%'
Но затем я перемещаю этот оператор в метод hibernate createQuery
Hibernate, как это:
public List<Projects> findAlike(String projectName, String customerName, String manager) {
Query q = getCurrentSession().createQuery("select p from projects p, managers m, wine_styles w where
lower(p.name) like :name and lower(p.customer) like :customer and lower(m.name) like :manager");
q.setParameter("name", "%" + projectName.toLowerCase() + "%");
q.setParameter("customer", "%" + customerName.toLowerCase() + "%");
q.setParameter("manager", "%" + manager.toLowerCase() + "%");
List<Projects> lo = (List<Projects>) q.getResultStream().distinct().collect(Collectors.toList());
return (List<Projects>) lo;
}
И у меня проблема в том, что когда я передаю name
и customer
все работает хорошо, я могу искать по нему, но поле manager
каждый раз возвращает все строкииз таблицы.
Я вызываю эту функцию для каждого KeyListener#keyReleased
вызова следующим образом:
@Override
public void keyReleased(KeyEvent e) {
NewProdForm.getData().setProjects(NewProdForm.getData().getProjectService().findAlike(projectInput.getText(), customerInput.getText(), projectManagerInput.getText()));
NewProdForm.getAppFrame().getProjectListPanel().getTm().fireTableDataChanged();
}
Также я обновляю tabelModel
каждый раз. Мой класс реализует KeyListener
, и в cosntructor я добавляю ключевой слушатель для каждого TextField
public class Search extends JPanel implements KeyListener {
private JTextField projectInput;
private JTextField customerInput;
private JTextField projectManagerInput;
private JTextField wineStyleInput;
private JTextField proposedLaunchDateInput;
private JTextField statusInput;
public Search() {
setLayout(null);
setBackground(Color.white);
projectInput = new JTextField();
customerInput = new JTextField();
projectManagerInput = new JTextField();
wineStyleInput = new JTextField();
proposedLaunchDateInput = new JTextField();
statusInput = new JTextField();
add(projectInput);
add(customerInput);
add(projectManagerInput);
add(wineStyleInput);
add(proposedLaunchDateInput);
add(statusInput);
projectInput.addKeyListener(this);
customerInput.addKeyListener(this);
projectManagerInput.addKeyListener(this);
}
}
Не знаю, что делать. Я ищу в Google, но все примеры, которые я нашел, показывают, что я делаю все правильно, но я уверен, что не так, потому что у меня нет результатов.
РЕДАКТИРОВАТЬ Так что после некоторых комментариев предложилЯ создал procedure
вот так
IF (OBJECT_ID('npd.searching') IS NOT NULL)
DROP PROCEDURE npd.searching
USE test001;
GO
CREATE PROCEDURE npd.searching
@project nvarchar(50),
@customer nvarchar(50),
@manager nvarchar(50),
@wine nvarchar(50)
AS
SET NOCOUNT ON;
select p.id, p.name, m.name from test001.npd.projects p
inner join test001.npd.managers m on p.manager_id = m.id
inner join test001.npd.wine_styles w on p.wine_style_id = w.id
where
lower(p.name) like '%' + @project + '%' and
lower(p.customer) like '%' + @customer + '%' and
lower(m.name) like '%' + @manager + '%' and
lower(w.name) like '%' + @wine + '%';
GO
и протестировал в SQL Management Studio вот так
EXEC npd.searching '', '', 'k', '';
Все работает так, как я хочу. Поэтому я также хочу перевести его в режим гибернации, чтобы я сделал что-то вроде
public List<Projects> findAlike(String projectName, String customerName, String manager, String wineStyle) {
Query q = getCurrentSession().createSQLQuery("EXEC npd.searching :name, :customer, :manager, :wine").addEntity(Projects.class);
q.setParameter("name", "'" + projectName.toLowerCase() + "'");
q.setParameter("customer", "'" + customerName.toLowerCase() + "'");
q.setParameter("manager", "'" + manager.toLowerCase() + "'");
q.setParameter("wine", "'" + wineStyle.toLowerCase() + "'");
List<Projects> lo = (List<Projects>) q.getResultStream().distinct().collect(Collectors.toList());
return (List<Projects>) lo;
}
, но когда я вызываю метод, я ничего не получаю, я имею в виду, что мой arraylist
, где я назначаю данные из запроса, пуст. Что с этим не так?
РЕДАКТИРОВАТЬ [РЕШЕНО]
Хорошо, через 2 часа поиска наконец-то нашли решение. Решение проблемы выше, которое я использую, было @NamedNativeQueries
. Поэтому я добавил
@NamedNativeQueries({
@NamedNativeQuery(
name = "searchProjects",
query = "EXEC npd.searching :project, :customer, :manager, :wine",
resultClass = Projects.class
)
})
и изменил метод findAlike
для использования @NamedNativeQuery
следующим образом:
@SuppressWarnings("unchecked")
public List<Projects> findAlike(String projectName, String customerName, String manager, String wineStyle) {
Query query = getCurrentSession().getNamedQuery("searchProjects"); // THIS LINE
query.setParameter("project", projectName.toLowerCase());
query.setParameter("customer", customerName.toLowerCase());
query.setParameter("manager", manager.toLowerCase());
query.setParameter("wine", wineStyle.toLowerCase());
List<Projects> foundProjects = (List<Projects>) query.getResultStream().distinct().collect(Collectors.toList());
return foundProjects;
}