【问题标题】:Grails belongsTo relationship fails on save due to null id由于空 id,Grails belongsTo 关系在保存时失败
【发布时间】:2015-12-25 11:02:40
【问题描述】:

我的 GORM 关系管理遇到了一些问题。基本上有 4 个域类在这个问题的范围内。一个House 是一个有多个Queue 的餐厅,每个餐厅都有多个Ticket。门票属于Customer

主要问题是当我创建一个Ticket 和一个Customer 和一个Queue 实例时,休眠抱怨customer_IDnullTicket 域类如下所示:

class Ticket implements Comparable<Ticket> {
    int number;
    boolean isValid;

    static belongsTo = [customer: Customer, queue: Queue]

    public Ticket(Customer customer, Queue queue,int number){
        println "Create ticket, customer: ${customer}, queue:${queue}, number:${number}";
        customer = customer;
        queue = queue;
        number = number;
        isValid = true;
    }
}

错误出现在我创建 Ticket 并保存它的一个控制器类中。

//c and q are Customer and Queue instances that have passed null check
Ticket t = new Ticket(c, q, 10);//In the constructor I see the Customer and Queue instances are not null indeed
t.save(flush: true);
if (t.hasErrors()) {
    log.error t.errors;
    return;
}

错误是一个空的Customer_ID,我不太明白。我已经将客户和队列传递到Ticket 构造函数中,但是为什么当我保存 Grails 时它似乎与 id 不匹配?我已验证客户 ID 已成功生成。请指出我在 GORM 设置中犯的错误。

Message: NULL not allowed for column "CUSTOMER_ID"; SQL statement: insert into ticket (id, version, customer_id, is_valid, number, queue_id) values (null, ?, ?, ?, ?, ?) [23502-176]

【问题讨论】:

    标签: java hibernate grails


    【解决方案1】:

    这实际上是参数和字段同名的阴影问题。只需像这样更改您的构造函数:

    class Ticket implements Comparable<Ticket> {
        int number;
        boolean isValid;
    
        static belongsTo = [customer: Customer, queue: Queue]
    
        public Ticket(Customer customer, Queue queue, int number) {
            println "Create ticket, customer: ${customer}, queue:${queue}, number:${number}";
            this.customer = customer;
            this.queue = queue;
            this.number = number;
            this.isValid = true;
        }
    }
    

    你必须在构造函数中使用this关键字,因为customerqueue等域字段被构造函数参数显示。

    https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html

    由于customer = customer,您将构造函数参数的值分配给自身,而不是您应该执行this.customer = customer(对所有其他人都一样)

    【讨论】:

    • 非常感谢!如果我错了,请纠正我,但我认为这以前有效。请详细说明您所说的“旧 Java 语法”是什么意思?
    • :-) “旧 Java 语法”是指开发人员可能遇到的基本 Java 问题。这解决了你的问题吗?
    • 像火花一样解决了。谢谢!
    • Grails 默认实现构造函数。在管理关系和域中的级联时,创建一个新的不是一个好主意。比如a中的关系belongsTo在另一边有很多关系,应该由addTo和removeFrom方法创建。
    猜你喜欢
    • 2020-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-30
    • 1970-01-01
    • 2013-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多