【问题标题】:stored procedure 'auto_pk_for_table' not found未找到存储过程“auto_pk_for_table”
【发布时间】:2017-04-10 12:51:46
【问题描述】:

我不知道为什么会收到错误消息:

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.
[...]

我正在使用卡宴:

<dependency>
    <groupId>org.apache.cayenne</groupId>
    <artifactId>cayenne-server</artifactId>
    <version>4.0.M5</version>
</dependency>

和用于 sql server 的 JDTS:

<dependency>
    <groupId>net.sourceforge.jtds</groupId>
    <artifactId>jtds</artifactId>
    <version>1.3.1</version>
</dependency>

连接没问题:

avr. 10, 2017 2:36:30 PM org.apache.cayenne.datasource.DriverDataSource getConnection
INFOS: +++ Connecting: SUCCESS.

我正在尝试创建一个新用户(我从 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

    }
}

编辑,添加信息:在我的用户对象中,我有一个用户 ID(主键),在 Cayenne 中我也将它写为主键并在 smallint 中。这个错误似乎是链接...https://cayenne.apache.org/docs/3.1/api/org/apache/cayenne/dba/sybase/SybasePkGenerator.html

【问题讨论】:

  • 当您使用 sql-server 标记问题时,为什么要使用 SybasePKGenerator?
  • (我对 cayenne 和 vaadin 还很陌生:我的代码可能犯了一个大错误)。我不知道我在哪里使用SybasePKGenerator,是不是因为我在cayenne中放了PK?我不这么认为,但我的数据库在 sql server 上。
  • SQLServerPkgenerator 扩展自 SybasePKGenerator,因此这并不表示存在问题。我将在下面的回复中解决实际问题。

标签: sql-server jakarta-ee vaadin apache-cayenne


【解决方案1】:

插入新对象时会发生错误。对于每个新对象,Cayenne 需要生成一个主键值。有多种策略可以做到这一点。默认策略取决于您使用的数据库。对于 SQLServer(和 Sybase,正如您所发现的 :)),该策略是使用特殊的存储过程。

要创建此存储过程(和其他支持的数据库对象),请转到 CayenneModeler,打开您的项目,然后选择“工具 > 生成数据库模式”。在“SQL 选项”选项卡中,取消选中除“创建主键支持”之外的所有复选框。您将在复选框下方的窗口中看到的 SQL 是您需要在 SQL 服务器上运行的。可以从 Cayenne 建模器执行此操作,也可以复制/粘贴到您最喜欢的数据库管理工具。

还有一个不需要存储过程的替代方案 - 使用数据库自​​动增量功能。为此,您需要转到 Modeler 中的每个 DbEntity,并在“Entity”选项卡下的“Pk Generation Strategy”下拉菜单中选择“Database-Generated”。这当然意味着您的 PK 列确实是数据库中的自动增量(这意味着您可能需要相应地调整您的数据库架构)。

【讨论】:

  • 谢谢!!!它正在工作。我更喜欢您的替代解决方案(添加自动增量)。我觉得这样更好,不是吗?
  • 是的,自动增量是我自己通常喜欢的。
  • 感谢您的帮助!这是非常非常有帮助的
  • 当我导出我的 CayenneDataObject 时,我没有主键的 getter 是否正常?我理解二传手,因为我对其进行了自动增量。但我应该能够得到主键,不是吗?谢谢
  • 您应该对此提出单独的 SO 问题,因为这是一个不相关的问题。但无论如何 - 是的,这是意料之中的。默认情况下,Cayenne 从对象属性中排除 PK 列(毕竟有一个抽象对象身份的不透明 DataObject.getObjectId())。但是,如果您愿意,您实际上可以将其显式映射到 ObjAttribute。或者使用“Cayenne.longPKForObject(..)”获取值。
猜你喜欢
  • 1970-01-01
  • 2021-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-25
  • 1970-01-01
相关资源
最近更新 更多