java @GeneratedValue (strategy = GenerationType.IDENTITY) 使用 MariaDB 10.4 和 eclipselink 的问题
Problems with java @GeneratedValue (strategy = GenerationType.IDENTITY) using MariaDB 10.4 and eclipselink
我正在 Java EE 中开发 REST Web 服务 我正在使用:Glassfish 5.0(build 25)、MariaDB 10.4 和 eclipselink(JPA 2.1)
这是我的代码:
commande_line table
CREATE TABLE IF NOT EXISTS `cooldb`.`commande_line` (
`id` INT NOT NULL AUTO_INCREMENT,
`quantity` INT NULL,
`discount` INT NULL,
`dish` INT NOT NULL,
`commande` INT NOT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `id_UNIQUE` (`id` ASC),
INDEX `fk_commande_line_dish1_idx` (`dish` ASC),
INDEX `fk_commande_line_commande1_idx` (`commande` ASC),
CONSTRAINT `fk_commande_line_dish1`
FOREIGN KEY (`dish`)
REFERENCES `cooldb`.`dish` (`id`)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `fk_commande_line_commande1`
FOREIGN KEY (`commande`)
REFERENCES `cooldb`.`commande` (`id`)
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;
persistance.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
<!-- Define Persistence Unit -->
<persistence-unit name="my_persistence_unit" transaction-type="JTA">
<jta-data-source>jdbc/mariadb</jta-data-source>
<class>com.yac.model.Address</class>
<class>com.yac.model.Commande</class>
<class>com.yac.model.CommandeLine</class>
<class>com.yac.model.Dish</class>
<class>com.yac.model.Dishtype</class>
<class>com.yac.model.Ingredient</class>
<class>com.yac.model.Payement</class>
<class>com.yac.model.Profil</class>
<class>com.yac.model.Restaurant</class>
<class>com.yac.model.Userapp</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
</properties>
</persistence-unit>
</persistence>
命令行实体
public class CommandeLine implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Integer id;
@Column(name = "quantity")
private Integer quantity;
@Column(name = "discount")
private Integer discount;
@JoinColumn(name = "commande", referencedColumnName = "id")
@ManyToOne(optional = false)
private Commande commande;
@JoinColumn(name = "dish", referencedColumnName = "id")
@ManyToOne(optional = false)
private Dish dish;
//Constructor
// Setter and Getter
}
命令行网络服务
@Stateless
@Path("commandeline")
public class CommandeLineFacadeREST extends AbstractFacade<CommandeLine> {
@PersistenceContext(unitName = "my_persistence_unit")
private EntityManager em;
public CommandeLineFacadeREST() {
super(CommandeLine.class);
}
@POST
@Override
@Consumes(MediaType.APPLICATION_JSON)
public void create(CommandeLine entity) {
super.create(entity);
}
@Override
protected EntityManager getEntityManager() {
return em;
}
}
抽象立面
public abstract class AbstractFacade<T> {
private Class<T> entityClass;
public AbstractFacade(Class<T> entityClass) {
this.entityClass = entityClass;
}
protected abstract EntityManager getEntityManager();
public void create(T entity) {
getEntityManager().persist(entity);
}
}
问题是当我使用 Postman 测试我的 Web 服务时,我尝试使用 POST 请求插入一条记录
这是我收到的错误消息:
Local Exception Stack:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.7.0.v20170811-d680af5): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLSyntaxErrorException: (conn=158) Table 'cooldb.sequence' doesn't exist
Error Code: 1146
Call: UPDATE SEQUENCE SET SEQ_COUNT = SEQ_COUNT + ? WHERE SEQ_NAME = ?
bind => [2 parameters bound]
Query: DataModifyQuery(name="SEQ_GEN_SEQUENCE" sql="UPDATE SEQUENCE SET SEQ_COUNT = SEQ_COUNT + ? WHERE SEQ_NAME = ?") ...
我不明白为什么当我使用@GeneratedValue (strategy = GenerationType.IDENTITY) 时 SEQUANCE 会出现问题。
当我更改 @GeneratedValue (strategy = GenerationType.SEQUENCE) 并使用以下脚本创建 table 时:
CREATE SEQUENCE SEQUANCE START WITH 1 INCREMENT BY 1;
通过应用如下所示的解决方案:Table 'customerjpa.sequence' doesn't exist JPA
但同样的问题
提前感谢您的帮助。
问题已通过 Chris 评论解决,我只需在我的 persistence.xml 文件中添加以下行:
<property name="eclipselink.target-database" value="MySQL"/>
非常感谢克里斯。
所以我的新 persistence.xml 文件是:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
<!-- Define Persistence Unit -->
<persistence-unit name="my_persistence_unit" transaction-type="JTA">
<jta-data-source>jdbc/mariadb</jta-data-source>
<class>com.yac.model.Address</class>
<class>com.yac.model.Commande</class>
<class>com.yac.model.CommandeLine</class>
<class>com.yac.model.Dish</class>
<class>com.yac.model.Dishtype</class>
<class>com.yac.model.Ingredient</class>
<class>com.yac.model.Payement</class>
<class>com.yac.model.Profil</class>
<class>com.yac.model.Restaurant</class>
<class>com.yac.model.Userapp</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="eclipselink.target-database" value="MySQL"/>
</properties>
</persistence-unit>
</persistence>
我只是在MariaDB基于它的persistence.xml文件中的MySQL中指定了数据库平台,因为列表中没有提到MariaDB。
如果还有其他建议,请不吝赐教。
另一个解决方案:
将 ?useMysqlMetadata=true
添加到您的 JDBC URL 连接,如下所示:
<property name="URL" value="jdbc:mariadb://[HOST]:[PORT]/[DB NAME]?useMysqlMetadata=true"/>
这将使 MariaDB 使用 MySQL 元数据,然后 eclipselink 会将其检测为 MySQL。
我正在 Java EE 中开发 REST Web 服务 我正在使用:Glassfish 5.0(build 25)、MariaDB 10.4 和 eclipselink(JPA 2.1) 这是我的代码:
commande_line table
CREATE TABLE IF NOT EXISTS `cooldb`.`commande_line` (
`id` INT NOT NULL AUTO_INCREMENT,
`quantity` INT NULL,
`discount` INT NULL,
`dish` INT NOT NULL,
`commande` INT NOT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `id_UNIQUE` (`id` ASC),
INDEX `fk_commande_line_dish1_idx` (`dish` ASC),
INDEX `fk_commande_line_commande1_idx` (`commande` ASC),
CONSTRAINT `fk_commande_line_dish1`
FOREIGN KEY (`dish`)
REFERENCES `cooldb`.`dish` (`id`)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `fk_commande_line_commande1`
FOREIGN KEY (`commande`)
REFERENCES `cooldb`.`commande` (`id`)
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;
persistance.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
<!-- Define Persistence Unit -->
<persistence-unit name="my_persistence_unit" transaction-type="JTA">
<jta-data-source>jdbc/mariadb</jta-data-source>
<class>com.yac.model.Address</class>
<class>com.yac.model.Commande</class>
<class>com.yac.model.CommandeLine</class>
<class>com.yac.model.Dish</class>
<class>com.yac.model.Dishtype</class>
<class>com.yac.model.Ingredient</class>
<class>com.yac.model.Payement</class>
<class>com.yac.model.Profil</class>
<class>com.yac.model.Restaurant</class>
<class>com.yac.model.Userapp</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
</properties>
</persistence-unit>
</persistence>
命令行实体
public class CommandeLine implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Integer id;
@Column(name = "quantity")
private Integer quantity;
@Column(name = "discount")
private Integer discount;
@JoinColumn(name = "commande", referencedColumnName = "id")
@ManyToOne(optional = false)
private Commande commande;
@JoinColumn(name = "dish", referencedColumnName = "id")
@ManyToOne(optional = false)
private Dish dish;
//Constructor
// Setter and Getter
}
命令行网络服务
@Stateless
@Path("commandeline")
public class CommandeLineFacadeREST extends AbstractFacade<CommandeLine> {
@PersistenceContext(unitName = "my_persistence_unit")
private EntityManager em;
public CommandeLineFacadeREST() {
super(CommandeLine.class);
}
@POST
@Override
@Consumes(MediaType.APPLICATION_JSON)
public void create(CommandeLine entity) {
super.create(entity);
}
@Override
protected EntityManager getEntityManager() {
return em;
}
}
抽象立面
public abstract class AbstractFacade<T> {
private Class<T> entityClass;
public AbstractFacade(Class<T> entityClass) {
this.entityClass = entityClass;
}
protected abstract EntityManager getEntityManager();
public void create(T entity) {
getEntityManager().persist(entity);
}
}
问题是当我使用 Postman 测试我的 Web 服务时,我尝试使用 POST 请求插入一条记录 这是我收到的错误消息:
Local Exception Stack:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.7.0.v20170811-d680af5): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLSyntaxErrorException: (conn=158) Table 'cooldb.sequence' doesn't exist
Error Code: 1146
Call: UPDATE SEQUENCE SET SEQ_COUNT = SEQ_COUNT + ? WHERE SEQ_NAME = ?
bind => [2 parameters bound]
Query: DataModifyQuery(name="SEQ_GEN_SEQUENCE" sql="UPDATE SEQUENCE SET SEQ_COUNT = SEQ_COUNT + ? WHERE SEQ_NAME = ?") ...
我不明白为什么当我使用@GeneratedValue (strategy = GenerationType.IDENTITY) 时 SEQUANCE 会出现问题。 当我更改 @GeneratedValue (strategy = GenerationType.SEQUENCE) 并使用以下脚本创建 table 时:
CREATE SEQUENCE SEQUANCE START WITH 1 INCREMENT BY 1;
通过应用如下所示的解决方案:Table 'customerjpa.sequence' doesn't exist JPA 但同样的问题
提前感谢您的帮助。
问题已通过 Chris 评论解决,我只需在我的 persistence.xml 文件中添加以下行:
<property name="eclipselink.target-database" value="MySQL"/>
非常感谢克里斯。 所以我的新 persistence.xml 文件是:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
<!-- Define Persistence Unit -->
<persistence-unit name="my_persistence_unit" transaction-type="JTA">
<jta-data-source>jdbc/mariadb</jta-data-source>
<class>com.yac.model.Address</class>
<class>com.yac.model.Commande</class>
<class>com.yac.model.CommandeLine</class>
<class>com.yac.model.Dish</class>
<class>com.yac.model.Dishtype</class>
<class>com.yac.model.Ingredient</class>
<class>com.yac.model.Payement</class>
<class>com.yac.model.Profil</class>
<class>com.yac.model.Restaurant</class>
<class>com.yac.model.Userapp</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="eclipselink.target-database" value="MySQL"/>
</properties>
</persistence-unit>
</persistence>
我只是在MariaDB基于它的persistence.xml文件中的MySQL中指定了数据库平台,因为列表中没有提到MariaDB。 如果还有其他建议,请不吝赐教。
另一个解决方案:
将 ?useMysqlMetadata=true
添加到您的 JDBC URL 连接,如下所示:
<property name="URL" value="jdbc:mariadb://[HOST]:[PORT]/[DB NAME]?useMysqlMetadata=true"/>
这将使 MariaDB 使用 MySQL 元数据,然后 eclipselink 会将其检测为 MySQL。