#java #sql-server #hibernate #jpa #optaplanner
Вопрос:
В настоящее время я кодирую с помощью optaplanner и использую SQL Server для базы данных.
моя система продолжает выдавать эту ошибку:
com.microsoft.sqlserver.jdbc.SQLServerException: Недопустимое имя столбца «stockLocations_StockLocationID»
Я проверил и все мои имена переменных в своей базе данных, и все они верны.
Вот мои текущие занятия:
классы shopify:
@PlanningEntity
@Entity
@DataSource("Shopify")
public class Shopify extends PanacheEntityBase{
@PlanningId
@Id
private Long ShopifyID;
private String CustomerName;
private String ProductSKU;
@PlanningVariable(valueRangeProviderRefs = "stocklocationRange")
@ManyToOne
private StockLocations stockLocations;
public Shopify(Long ShopifyID, String customerName, String productSKU) {
this.ShopifyID = ShopifyID;
this.CustomerName = customerName;
this.ProductSKU = productSKU;
}
public Shopify(Long shopifyID, String customerName, String productSKU, StockLocations
stockLocations) {
ShopifyID = shopifyID;
CustomerName = customerName;
ProductSKU = productSKU;
this.stockLocations = stockLocations;
}
Класс размещения запасов:
@Entity
@DataSource("StockLocations")
public class StockLocations extends PanacheEntityBase {
@PlanningId
@Id
@GeneratedValue
public Long StockLocationID;
public String ProductSKU;
public String StockLocation;
public StockLocations(Long stockLocationID, String productSKU, String stock_Location) {
this.StockLocationID = stockLocationID;
ProductSKU = productSKU;
StockLocation = stock_Location;
}
public StockLocations() {
}
Класс allDetails
@PlanningSolution
public class AllDetails {
@PlanningEntityCollectionProperty
private List<Shopify> shopifyList;
@ProblemFactCollectionProperty
@ValueRangeProvider(id = "stocklocationRange")
private List<StockLocations> stockLocationsList;
@PlanningScore
private HardSoftScore score ;
private SolverStatus solverStatus;
public AllDetails(){
}
public AllDetails( List<StockLocations> stockLocationsList, List<Shopify> shopifyList) {
this.stockLocationsList = stockLocationsList;
this.shopifyList = shopifyList;
// this.shopifyStockLocationsList = shopifyStockLocationsList;
}
а вот основной функциональный файл javascript, используемый для отображения данных в пользовательском интерфейсе
function refreshAllDetails() {
$.getJSON("allDetails", function (allDetails) {
refreshSolvingButtons(allDetails.solverStatus != null amp;amp; allDetails.solverStatus !==
"NOT_SOLVING");
$("#score").text("Score: " (allDetails.score == null ? "?" : allDetails.score));
const timeTableByRoom = $("#timeTableByRoom");
timeTableByRoom.children().remove();
const timeTableByTeacher = $("#timeTableByTeacher");
timeTableByTeacher.children().remove();
const timeTableByStudentGroup = $("#timeTableByStudentGroup");
timeTableByStudentGroup.children().remove();
const unassignedSKUs = $("#unassignedSKUs");
unassignedSKUs.children().remove();
//Picking Station Function
const theadByRoom = $("<thead>").appendTo(timeTableByRoom);
const headerRowByRoom = $("<tr>").appendTo(theadByRoom);
headerRowByRoom.append($("<th>Picking Stations</th>"));
$.each(allDetails.stockLocationsList, (index, stockLocations) => {
headerRowByRoom
.append($("<th/>")
.append($("<span/>").text(stockLocations.stockLocation))
.append($(`<button type="button" class="ml-2 mb-1 btn btn-light btn-sm p-
1"/>`)
.append($(`<small class="fas fa-trash"/>`)
).click(() => deleteRoom(stockLocations))));
});
//IT WORKS!!! UNASSIGNED SKUS
$.each(allDetails.shopifyList, (index, shopify) => {
const color = pickColor(shopify.product_SKU)
const lessonElementWithoutDelete = $(`<div class="card lesson" style="background-
color: ${color}"/>`)
.append($(`<div class="card-body p-2"/>`)
.append($(`<h5 class="card-title mb-1"/>`).text(shopify.customerName))
.append($(`<p class="card-text ml-2 mb-1"/>`)
.append($(`<em/>`).text(`Product SKU: ${shopify.product_SKU}`)))
.append($(`<small class="ml-2 mt-1 card-text text-muted align-bottom float
right"/>`).text(shopify.id)))
//append($(`<p class="card-text ml-2"/>`).text(shopify.billing_Name_Added)));
const lessonElement = lessonElementWithoutDelete.clone();
lessonElement.find(".card-body").prepend(
$(`<button type="button" class="ml-2 btn btn-light btn-sm p-1 float-right"/>`)
.append($(`<small class="fas fa-trash"/>`)
).click(() => deleteLesson(shopify))
)
if (Shopify.stockLocations == null) {
unassignedSKUs.append(lessonElement);
}
});
});
}
Ответ №1:
Это проблема с гибернацией JPA и JDBC, которая не связана с OptaPlanner.
«com.microsoft.sqlserver.jdbc.SQLServerException: Недопустимое имя столбца «stockLocations_StockLocationID»»
Это означает, что эта конфигурация Hibernate-JPA:
@Entity ...
public class StockLocations extends PanacheEntityBase {
...
@Id
@GeneratedValue
public Long StockLocationID;
не соответствует схеме таблицы базы данных. В таблице SQL для этой сущности нет столбца SQL с именем SotckLocationID. Вероятно, это только верхушка айсберга.
В программе быстрого запуска optaplanner quarkus-школьное расписание, мы используем
quarkus.hibernate-orm.database.generation=drop-and-create
уничтожить всю базу данных и моделировать ее на 100%, как модель, каждый раз, когда она запускается. Это отлично подходит для разработки по мере изменения модели (очевидно, очень плохо для производства).
Комментарии:
1. Моя база данных содержит поле, и имя в коде также правильное, я, кажется, не могу понять, почему оно продолжает выдавать эту ошибку, но я попробую ваш код кваркуса, спасибо!
2. существуют ли какие-либо примеры optaplanner, в которых используются реальные базы данных?
3. быстрый запуск quarkus-school-расписания использует базу данных H2 в памяти. Его можно легко переключить на postgresql, mysql, mariadb и т.д. Для получения информации о том, как это сделать, перейдите в quarkus-quickstarts и найдите примеры hibernate-jpa или panache, в которых используется postgresql.