Hibernate不能生成id(Hibernate can't generate id)
我在我的IntelliJ IDEA上创建了一个新项目,使用hibernate(+ hibernate entitymanager)5,hsqldb 1.8(仅用于测试)以及junit 4。
我有我的测试课
UserRoundRelationsTest
EntityManagerFactory emf; EntityManager em; Date currentDate; User user; Round round1; Round round2;
还有一些@After和@Before方法:
@Before public void saveDummyUserAndTwoDummyRounds() { emf = Persistence.createEntityManagerFactory("testPersistence"); em = emf.createEntityManager(); // Retrieve an application managed entity manager currentDate = new Date(); user = new User.UserBuilder("alias").fullName("Full Name").phoneNumber("Phone Number").height(100).weight(100).birthDate(currentDate).build(); round1 = new Round(new GameMode(1, ButtonTargetStrategy.RANDOM, ButtonSkipStrategy.SKIP_ON_MISTAKE)); round2 = new Round(new GameMode(2, ButtonTargetStrategy.RANDOM, ButtonSkipStrategy.SKIP_ON_MISTAKE)); round1.setUser(user); round2.setUser(user); HashSet<Round> rounds = new HashSet<Round>(2); rounds.add(round1); rounds.add(round2); em.getTransaction().begin(); user.setRounds(rounds); em.persist(user); em.persist(round1); em.persist(round2); em.flush(); em.getTransaction().commit(); }
和
@After public void deleteData() { em.remove(user); em.remove(round2); em.remove(round2); em.getTransaction().commit(); em.close(); emf.close(); }
首先,当我尝试运行测试时,hibernate无法找到User和Round类的表以及它们依赖的所有内容(例如,称为ButtonPress的类)。 我认为这是由于我在persistence.xml中配置的自动创建 - 删除
<persistence-unit name="testPersistence"> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <class>com.carloworks.model.User</class> <class>com.carloworks.model.Round</class> <class>com.carloworks.model.ButtonPress</class> <properties> <!--<property name="hibernate.archive.autodetection" value="class,hbm"></property>--> <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"></property> <property name="hibernate.show_sql" value="true"></property> <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"></property> <property name="hibernate.connection.username" value="sa"></property> <property name="hibernate.connection.password" value=""></property> <property name="hibernate.connection.url" value="jdbc:hsqldb:mem:buttonMasherModelsTestDb;MV_STORE=FALSE;MVCC=FALSE"></property> <!--<property name="hibernate.default_schema" value="buttonMasherModelsTestDb"/>--> <property name="hibernate.hbm2ddl.auto" value="create-drop"></property> </properties> </persistence-unit>
进一步向下滚动错误日志,我也在这一行发生错误:
em.persist(user);
空标识符(加'不支持此函数'/'GenericJDBCException:无法准备语句')。
我做错了什么?
该项目也在Github上提供
完整的错误日志
I've created a new project on my IntelliJ IDEA, using hibernate (+ hibernate entitymanager) 5, hsqldb 1.8 (for testing only), as well as junit 4.
I've got my test class
UserRoundRelationsTest
EntityManagerFactory emf; EntityManager em; Date currentDate; User user; Round round1; Round round2;
And some @After and @Before methods:
@Before public void saveDummyUserAndTwoDummyRounds() { emf = Persistence.createEntityManagerFactory("testPersistence"); em = emf.createEntityManager(); // Retrieve an application managed entity manager currentDate = new Date(); user = new User.UserBuilder("alias").fullName("Full Name").phoneNumber("Phone Number").height(100).weight(100).birthDate(currentDate).build(); round1 = new Round(new GameMode(1, ButtonTargetStrategy.RANDOM, ButtonSkipStrategy.SKIP_ON_MISTAKE)); round2 = new Round(new GameMode(2, ButtonTargetStrategy.RANDOM, ButtonSkipStrategy.SKIP_ON_MISTAKE)); round1.setUser(user); round2.setUser(user); HashSet<Round> rounds = new HashSet<Round>(2); rounds.add(round1); rounds.add(round2); em.getTransaction().begin(); user.setRounds(rounds); em.persist(user); em.persist(round1); em.persist(round2); em.flush(); em.getTransaction().commit(); }
and
@After public void deleteData() { em.remove(user); em.remove(round2); em.remove(round2); em.getTransaction().commit(); em.close(); emf.close(); }
Firstly, when I try to run the test, hibernate can't find the tables for User and Round classes, as well as everything they are dependent on (a class called ButtonPress for example). I assume this happens due to the automatic create-drop I have configured at my persistence.xml
<persistence-unit name="testPersistence"> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <class>com.carloworks.model.User</class> <class>com.carloworks.model.Round</class> <class>com.carloworks.model.ButtonPress</class> <properties> <!--<property name="hibernate.archive.autodetection" value="class,hbm"></property>--> <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"></property> <property name="hibernate.show_sql" value="true"></property> <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"></property> <property name="hibernate.connection.username" value="sa"></property> <property name="hibernate.connection.password" value=""></property> <property name="hibernate.connection.url" value="jdbc:hsqldb:mem:buttonMasherModelsTestDb;MV_STORE=FALSE;MVCC=FALSE"></property> <!--<property name="hibernate.default_schema" value="buttonMasherModelsTestDb"/>--> <property name="hibernate.hbm2ddl.auto" value="create-drop"></property> </properties> </persistence-unit>
Scrolling further down the error logs, I also get an error at this line:
em.persist(user);
null identifier (plus 'This function is not supported'/'GenericJDBCException: could not prepare statement').
What did I do wrong?
The project is also available on Github
Full Error Log
原文:https://stackoverflow.com/questions/41063083
最满意答案
如果您使用某些符号通过某些
#if
预处理程序指令进行测试,那么该符号应该在预处理时定义(这在C ++编译器实际解析源文件之前发生)。所以你可能想要使用
#define HORIZONTAL_PIXELS 240
代替
static const uint8_t HORIZONTAL_PIXELS = 240;
如果你真的需要这样一个
const
你可以用它来命名:static const uint8_t k_HORIZONTAL_PIXELS = HORIZONTAL_PIXELS;
阅读有关C&C ++预处理器的更多信息。 如果你有一个源文件
foo.cc
尝试获取其预处理表单g++ -C -E foo.cc > foo.ii
(也许添加其他预处理标志,如
-I
...或-D
....)然后用寻呼机或编辑器查看生成的foo.ii
if you use some symbol to be tested by some
#if
preprocessor directive, that symbol should be defined at preprocessing time (which happens before the actual parsing of your source file by the C++ compiler).So you probably want to use
#define HORIZONTAL_PIXELS 240
instead of
static const uint8_t HORIZONTAL_PIXELS = 240;
If you really need such a
const
you could name it otherwise:static const uint8_t k_HORIZONTAL_PIXELS = HORIZONTAL_PIXELS;
Read more about the C & C++ preprocessor. If you have a source file
foo.cc
try to get its preprocessed form withg++ -C -E foo.cc > foo.ii
(perhaps adding other preprocessing flags like
-I
... or-D
....) then look with a pager or an editor into the generatedfoo.ii
相关问答
更多-
static_cast是您应该尝试使用的第一个演员。 它实现类型之间的隐式转换(如int到float或指向void*指针),它也可以调用显式转换函数(或隐式转换函数)。 在许多情况下,明确说明static_cast不是必需的,但重要的是要注意, T(something)语法等同于(T)something ,应该避免(稍后再说)。 然而, T(something, something_else)是安全的,并且保证调用构造函数。 static_cast也可以通过继承层次结构进行转换。 向上(向基类)向上投射是不 ...
-
const_cast是否安全?(Is const_cast safe?)[2023-06-07]
const_cast只有在您投射一个原始为非const的变量时才是安全的。 例如,如果您有一个函数接受一个const char *的参数,并且传入一个可修改的char * ,那么const_cast将该参数返回到char *并进行修改是安全的。 但是,如果原始变量实际上是const ,那么使用const_cast会导致未定义的行为。 void func(const char *param, size_t sz, bool modify) { if(modify) strncpy(co ... -
static const vs #define(static const vs #define)[2023-09-05]
就个人而言,我不喜欢预处理器,所以我总是和const一起去。 #define的主要优点是它不需要内存来存储在程序中,因为它只是用文字值替换一些文本。 它还具有没有类型的优点,因此它可以用于任何整数值而不产生警告。 “const”的优点在于它们可以被限定,并且可以在需要传递对象的指针的情况下使用它们。 虽然我不知道你在“静态”部分得到什么。 如果你在全球宣布,我会将它放在一个无声的命名空间中,而不是使用静态。 例如 namespace { unsigned const seconds_per_minut ... -
如何在预处理器(#if)中转换静态const以避免溢出(How to cast static const in the preprocessor (#if) to avoid overflow)[2023-04-28]
如果您使用某些符号通过某些#if预处理程序指令进行测试,那么该符号应该在预处理时定义(这在C ++编译器实际解析源文件之前发生)。 所以你可能想要使用 #define HORIZONTAL_PIXELS 240 代替 static const uint8_t HORIZONTAL_PIXELS = 240; 如果你真的需要这样一个const你可以用它来命名: static const uint8_t k_HORIZONTAL_PIXELS = HORIZONTAL_PIXELS; 阅读有关C&C ... -
我怎么能绕过这个? 选项1 您可以在运行时测试版本并调用合适的函数或使用代码块。 int main() { std::cout << "Code for any version\n"; if ( isVersionSix() ) { std::cout << "Additional code for version 6.0\n"; } return 0; } 选项2 如果在运行时分支不是选项,则可以使用函数模板,该函数模板是先前版本的noop,并且 ...
-
是否可以在成员例程中使用const_cast来避免重复的代码(is it ok to use const_cast in member routines to avoid duplicated code)[2024-01-14]
不,我不建议这样做。 我建议你反向使用const_cast : int& get() { return const_cast(const_cast(*this).get()); }; const int& get() const { return m_someData; }; 也就是说,你应该从非const重载调用const成员函数,而不是相反。 这样,你确保即使非const版本也不会改变对象的状态,并且两个函数中的代码确实相同 (因为你最终调用了const版本) - ... -
Static Cast访问静态const类成员[duplicate](Static Cast to access static const class member [duplicate])[2022-04-09]
类中static成员的声明,如static const int test = 5; 是一个声明但不是定义,即使它有一个初始化器。 声明通常应该有相应的定义。 这个定义看起来像const int A::test; (这不是“前瞻性声明”。) 但是,还有一个额外的规则,即如果只使用其值,不使用其地址,并且没有引用绑定到它(这与获取其地址类似),则不需要定义整数类型的static const类成员。 你正在调用的函数是void std::vector::push_back(const int&); 。 ... -
你在第二级抛弃了const , static_cast不允许这样做(实际上,除了const_cast之外没有任何“C ++”): void const* char const* * // ^^^^^^^^^^^ ^^^^^ // pointee cv-qualifiers // of pointee 相反,写 const char *ca = *(static_cast
... -
const_cast被指定用于执行非常具体的操作。 它可以将左值转换为左值引用,将右值转换为右值引用。 它可以在指针之间进行转换。 它不能从右值转换为左值引用,甚至是const值。 阅读5.2.11以获得演员可以做的确切列表; 该部分没有列出什么,它不能做。 static_cast可以执行其他操作,如5.2.9中所列。 其中,它可以从rvalue转换为lvalue对const的引用。 const_cast is specified to do very specific things. It can con ...
-
TemplClass
和TemplClass 是不相关的类型。 例如,您可能具有(部分)专业化以使它们真正不同: template class TemplClass { void generic(); std::string s; }; template class TemplClass { void foo(); std::vector v; }; 将一个投入另一个没有意义。 ...