Sql server 未找到存储过程“自动\u pk\u for_table”
我不知道我为什么会收到错误:Sql server 未找到存储过程“自动\u pk\u for_table”,sql-server,jakarta-ee,vaadin,apache-cayenne,Sql Server,Jakarta Ee,Vaadin,Apache Cayenne,我不知道我为什么会收到错误: org.apache.cayenne.CayenneRuntimeException: [v.4.0.M5 Feb 24 2017 07:47:55] Commit Exception [...] Caused by: java.sql.SQLException: Procédure stockée 'auto_pk_for_table' introuvable. [...] 我使用的是Cayenne: <dependency> <gro
org.apache.cayenne.CayenneRuntimeException: [v.4.0.M5 Feb 24 2017 07:47:55] Commit Exception
[...]
Caused by: java.sql.SQLException: Procédure stockée 'auto_pk_for_table' introuvable.
[...]
我使用的是Cayenne:
<dependency>
<groupId>org.apache.cayenne</groupId>
<artifactId>cayenne-server</artifactId>
<version>4.0.M5</version>
</dependency>
我正在尝试创建一个新用户,我将从bascis开始!所以我的代码是:
我剪了一点,太长了:
public abstract class _UserInfo extends CayenneDataObject {
public static final String ADDRESS_PROPERTY = "address";
public void setAddress(String address) {
writeProperty(ADDRESS_PROPERTY, address);
}
public String getAddress() {
return (String)readProperty(ADDRESS_PROPERTY);
}
}
public class UserInfo extends _UserInfo implements Serializable {
private static final long serialVersionUID = 1L;
public String address;
public String getAdress() {
return address;
}
public void setAddress(String address) {
super.setAddress(address);
}
//I have the hashcode and equals too
}
然后,我使用vaadin创建了我的表单:
public class UserAddView extends CustomComponent implements View {
private static final long serialVersionUID = 1L;
private TextField address;
private Button save;
public static final String USERVIEW = "user";
public boolean checkValidation() {
if (!checkTextFieldValid(address))
return false;
return true;
}
public boolean checkTextFieldValid(TextField element) {
if (element == null || element.isEmpty()) {
Notification.show(
"You should register a " + element.getDescription(),
Type.WARNING_MESSAGE);
return false;
}
return true;
}
public UserAddView() {
VerticalLayout mainLayout = new VerticalLayout();
mainLayout.setSizeFull();
setCompositionRoot(mainLayout);
final VerticalLayout vlayout = new VerticalLayout();
address = new TextField("Address:");
address.setDescription("Address");
vlayout.addComponent(address);
save = new Button("Save");
vlayout.addComponent(save);
mainLayout.addComponent(new HeaderMenu());
mainLayout.addComponent(vlayout);
addListeners();
}
private void addListeners() {
save.addClickListener(new ClickListener() {
private static final long serialVersionUID = 1L;
@Override
public void buttonClick(ClickEvent event) {
if (checkValidation() == true) {
ServerRuntime cayenneRuntime = ServerRuntime.builder()
.addConfig("cayenne-myapplication.xml").build();
ObjectContext context = cayenneRuntime.newContext();
UserInfo user = context.newObject(UserInfo.class);
user.setAddress(address.getValue());
user.getObjectContext().commitChanges();
Notification.show(
"Has been saved, We will send you your password by email. Your user login is: "
+ email.getValue(), Type.TRAY_NOTIFICATION);
getUI().getNavigator().navigateTo(HomepageView.MAINVIEW);
}
}
});
}
@Override
public void enter(ViewChangeEvent event) {
// TODO Auto-generated method stub
}
}
编辑、添加信息:在我的用户对象中,我有一个userid主键,在cayenne中,我也将其作为主键写入了smallint中。此错误似乎是链接 插入新对象时会发生错误。对于每个新对象,Cayenne需要生成主键的值。有各种各样的策略可以做到这一点。默认策略取决于您使用的数据库。对于SQLServer和Sybase,正如您所发现的:该策略是使用一个特殊的存储过程 要创建此存储过程和其他支持的DB对象,请转到CayenneModeler,打开项目,然后选择工具>生成数据库架构。在“SQL选项”选项卡中,取消选中除“创建主键支持”之外的所有复选框。您将在复选框下方的窗口中看到的SQL是您需要在SQL server上运行的SQL。可以从Cayenne modeler执行此操作,也可以复制/粘贴到您喜爱的数据库管理工具
还有一种不需要存储过程的替代方法-使用DB自动增量功能。为此,您需要转到Modeler中的每个DbEntity,并在Entity选项卡下选择Pk Generation Strategy下拉列表中生成的数据库。这当然意味着您的PK列确实是DB中的一个自动增量,这意味着您可能需要相应地调整DB架构。当您使用sql server标记问题时,为什么要使用SybasePKGenerator?我对cayenne和vaadin非常陌生:我可能在代码中犯了一个大错误。我不知道我在哪里使用SybasePKGenerator,是因为我在cayenne中使用了PK吗?我不这么认为,但我的数据库位于sql server上。SQLServerPkgenerator从SybasePKGenerator扩展而来,因此这并不表示存在问题。我将在下面的回复中解决实际问题。谢谢!!!它起作用了。我更喜欢您的替代解决方案添加自动增量。我觉得它更好,不是吗?是的,我通常更喜欢自动增值。谢谢你的帮助!当我导出CayenneDataObject时,它非常有用,我没有主键的getter是正常的吗?我理解setter,因为我在它上面加了一个自动增量。但我应该能拿到主键,不是吗?谢谢你应该就这个问题单独提问,因为这是一个无关的问题。但无论如何——是的,这是意料之中的。默认情况下,Cayenne将PK列从对象属性中排除,因为存在抽象对象标识的不透明DataObject.getObjectId。但如果需要,实际上可以将其显式映射到ObjAttribute。或者使用Cayenne.longPKForObject。。以检索该值。
public abstract class _UserInfo extends CayenneDataObject {
public static final String ADDRESS_PROPERTY = "address";
public void setAddress(String address) {
writeProperty(ADDRESS_PROPERTY, address);
}
public String getAddress() {
return (String)readProperty(ADDRESS_PROPERTY);
}
}
public class UserInfo extends _UserInfo implements Serializable {
private static final long serialVersionUID = 1L;
public String address;
public String getAdress() {
return address;
}
public void setAddress(String address) {
super.setAddress(address);
}
//I have the hashcode and equals too
}
public class UserAddView extends CustomComponent implements View {
private static final long serialVersionUID = 1L;
private TextField address;
private Button save;
public static final String USERVIEW = "user";
public boolean checkValidation() {
if (!checkTextFieldValid(address))
return false;
return true;
}
public boolean checkTextFieldValid(TextField element) {
if (element == null || element.isEmpty()) {
Notification.show(
"You should register a " + element.getDescription(),
Type.WARNING_MESSAGE);
return false;
}
return true;
}
public UserAddView() {
VerticalLayout mainLayout = new VerticalLayout();
mainLayout.setSizeFull();
setCompositionRoot(mainLayout);
final VerticalLayout vlayout = new VerticalLayout();
address = new TextField("Address:");
address.setDescription("Address");
vlayout.addComponent(address);
save = new Button("Save");
vlayout.addComponent(save);
mainLayout.addComponent(new HeaderMenu());
mainLayout.addComponent(vlayout);
addListeners();
}
private void addListeners() {
save.addClickListener(new ClickListener() {
private static final long serialVersionUID = 1L;
@Override
public void buttonClick(ClickEvent event) {
if (checkValidation() == true) {
ServerRuntime cayenneRuntime = ServerRuntime.builder()
.addConfig("cayenne-myapplication.xml").build();
ObjectContext context = cayenneRuntime.newContext();
UserInfo user = context.newObject(UserInfo.class);
user.setAddress(address.getValue());
user.getObjectContext().commitChanges();
Notification.show(
"Has been saved, We will send you your password by email. Your user login is: "
+ email.getValue(), Type.TRAY_NOTIFICATION);
getUI().getNavigator().navigateTo(HomepageView.MAINVIEW);
}
}
});
}
@Override
public void enter(ViewChangeEvent event) {
// TODO Auto-generated method stub
}
}