Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA复合外键_Java_Mysql_Spring_Hibernate_Jpa - Fatal编程技术网

Java JPA复合外键

Java JPA复合外键,java,mysql,spring,hibernate,jpa,Java,Mysql,Spring,Hibernate,Jpa,因此,我目前有一个包含用户信息的数据库,定义用户的是用户id 然后我有一个名为token的表,它有一个token\u id和user\u id作为主键和其余的信息,这使它成为一个一对多数据库 @Entity @Table(name = "user") public class User implements Serializable { @Id @Column(name = "user_id") private long userId; //Other varia

因此,我目前有一个包含用户信息的数据库,定义用户的是用户id

然后我有一个名为token的表,它有一个token\u id和user\u id作为主键和其余的信息,这使它成为一个一对多数据库

@Entity
@Table(name = "user")
public class User implements Serializable {
    @Id
    @Column(name = "user_id")
    private long userId;
    //Other variables and getters and setters

    @OneToMany(orphanRemoval = true, mappedBy = "user", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @Access(AccessType.PROPERTY) //I need this as is since I have other things in the setter 
    private List<Token> tokens = new ArrayList<>();

    public List<Token> getTokens() {
        return tokens;
    }

    public void setTokens(List<Token> tokens) {
        this.tokens = tokens;
    }
}
现在,出于某种原因,只要
用户
没有标记为@Id,它就会工作(即使在数据库中它是主键)

任何帮助

application.properties:

spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL57InnoDBDialect

spring.jpa.show-sql=true
logging.level.org.hibernate.type=TRACE
SQL输出:

Hibernate: insert into tokens (date_created, last_used, token, user_id, token_id) values (?, ?, ?, ?, ?)
binding parameter [1] as [TIMESTAMP] - [2018-05-14T08:29:00.719764Z]
binding parameter [2] as [TIMESTAMP] - [null] //This is okay to be null this is last_used
binding parameter [3] as [VARCHAR] - [<Token too long to write in question>] //Actual data type is LONGTEXT
binding parameter [4] as [BIGINT] - [null] //this is a problem (user_id should not be - should be a long numebr such as: 5531405900210671089)
binding parameter [5] as [BIGINT] - [0] //this is a problem (token_id should be a long number such as: -8824825685434914749)
SQL Error: 1048, SQLState: 23000
Column 'user_id' cannot be null
Hibernate:插入令牌(创建日期、上次使用日期、令牌、用户标识、令牌标识)值(?,,,?,?)
绑定参数[1]为[TIMESTAMP]-[2018-05-14T08:29:00.719764Z]
将参数[2]绑定为[TIMESTAMP]-[null]//可以为null这是最后一次使用
将参数[3]绑定为[VARCHAR]-[]//实际数据类型为LONGTEXT
将参数[4]绑定为[BIGINT]-[null]//这是一个问题(用户id不应该是-应该是一个长numebr,例如:5531405900210671089)
将参数[5]绑定为[BIGINT]-[0]//这是一个问题(令牌id应该是一个长数字,例如:-882482568543494749)
SQL错误:1048,SQLState:23000
“用户id”列不能为空

您不需要在Token中用@id注释用户id:您看到了这一点。 同样,在数据库中,将表令牌的主键定义为tokednId就足够了。 当然,必须将用户id设置为不应为空的外键。

这是一个“派生标识”,因此
令牌需要一个
@IdClass
,如下所示:

public class TokenId implements Serializable {
    private long tokenId; // matches the name of the attribute
    private long user;  // matches name of attribute and type of User PK
    ...
}
@Entity
@IdClass(TokenId.class)
public class Token {
    ...
}
然后,
Token
需要像这样指定它的
@IdClass

public class TokenId implements Serializable {
    private long tokenId; // matches the name of the attribute
    private long user;  // matches name of attribute and type of User PK
    ...
}
@Entity
@IdClass(TokenId.class)
public class Token {
    ...
}

JPA 2.1规范第2.4.1节中讨论了派生标识(带有示例)。

是的,这就是我现在要做的,但我不明白@Id在本上下文中不起作用的原因。请定义“不起作用”。您想要一个由
令牌id
用户id
组成的id吗?如果是这样,则需要
@IdClass
@EmbeddedId
。否则,您应该只在一个属性上放置
@Id
。是的,这正是我想要的,但我似乎没有让它与IdClass或EmbeddedId一起工作