Hibernate不会在级联上生成子ID所有保存(Hibernate not generating child id on cascade all save)
家长班:
@Entity @Table(name = "****") @Audited public class Ship { @Id @Column(name = "id") @GeneratedValue(generator = "uuid") @GenericGenerator(name = "uuid", strategy = "uuid") private String id; @OneToMany(mappedBy = "associatedShip", cascade = CascadeType.ALL, fetch = FetchType.EAGER) private List<ShipLoadlineInformation> loadlineInformation = new ArrayList<ShipLoadlineInformation>(0); .. with other fields constructors, getters and setters. }
儿童班:
@Entity @Table(name = "*********") @Audited public class ShipLoadlineInformation { @Id @Column(name = "id") @GeneratedValue(generator = "uuid") @GenericGenerator(name = "uuid", strategy = "uuid") private String id; @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "ASSOCIATED_SHIP") private Ship associatedShip; .. with other fields, constructors, getter and setters }
我将它保存在我的DAO中,如下所示:
this.sessionFactory.getCurrentSession().save(ship);
当我尝试保存对象时,它会给我以下错误:
org.hibernate.NonUniqueObjectException:具有相同标识符值的另一个对象已与会话关联:[com.tms.model.transportMode.ShipLoadlineInformation#] at org.hibernate.engine.internal.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java: 618)〜[hibernate-core-4.3.11.Final.jar:4.3.11.Final] org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:301)〜[hibernate-core-4.3.11 .Final.jar:4.3.11.Final]在org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:244)〜[hibernate-core-4.3.11.Final.jar:4.3.11.Final]在org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:109)〜[hibernate-core-4.3.11.Final.jar:4.3.11.Final] org.hibernate.event.internal.DefaultSaveOrUpdateEventListener。 onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)〜[hibernate -core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:684)〜[hibernate-core-4.3.11.Final.jar:4.3。 11.Final]在org.hibernate.spi上的org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:676)〜[hibernate-core-4.3.11.Final.jar:4.3.11.Final]。在org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:350)的CascadingActions $ 5.cascade(CascadingActions.java:235)〜[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 〜[hibernate-core-4.3.11.Final.jar:4.3.11.Final]在org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:293)〜[hibernate-core-4.3.11.Final .jar:4.3.11.Final] org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)~ [hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org .hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:379)〜[hibernate-core-4.3.11.Final.jar:4.3.11.Final] org.hibernate.engine.internal.Cascade.cascadeCollection( Cascade.java:319)~ [hibern ate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:296)~ [hibernate-core-4.3.11.Final.jar :4.3.11.Final]在org.hibernate的org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)〜[hibernate-core-4.3.11.Final.jar:4.3.11.Final] .engine.internal.Cascade.cascade(Cascade.java:118)~ [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
在调试它时,发现父类的id正在生成。 但是没有生成子类的id。
我认为这是原因。 如果我错了,请纠正我。
任何帮助表示赞赏。
谢谢。
Parent Class:
@Entity @Table(name = "****") @Audited public class Ship { @Id @Column(name = "id") @GeneratedValue(generator = "uuid") @GenericGenerator(name = "uuid", strategy = "uuid") private String id; @OneToMany(mappedBy = "associatedShip", cascade = CascadeType.ALL, fetch = FetchType.EAGER) private List<ShipLoadlineInformation> loadlineInformation = new ArrayList<ShipLoadlineInformation>(0); .. with other fields constructors, getters and setters. }
Child class:
@Entity @Table(name = "*********") @Audited public class ShipLoadlineInformation { @Id @Column(name = "id") @GeneratedValue(generator = "uuid") @GenericGenerator(name = "uuid", strategy = "uuid") private String id; @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "ASSOCIATED_SHIP") private Ship associatedShip; .. with other fields, constructors, getter and setters }
I am saving it in my DAO as follows:
this.sessionFactory.getCurrentSession().save(ship);
When i try to save the object ship its giving me following error:
org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [com.tms.model.transportMode.ShipLoadlineInformation#] at org.hibernate.engine.internal.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:618) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:301) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:244) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:109) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:684) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:676) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.engine.spi.CascadingActions$5.cascade(CascadingActions.java:235) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:350) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:293) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:379) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:319) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:296) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:118) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
When debugging it, found out that the id for the parent class is getting generated. But the id for child class is not being generated.
I think this is the cause. Correct me if i am wrong.
Any help is appreciated.
Thanks.
原文:https://stackoverflow.com/questions/35319735
最满意答案
编辑2:我将CreateFile更改为CreateFileA,这是它给我的eroor代码(驱动器D是USB,它不是硬盘)
这是一个完全不同的问题,与
wchar_t
无关。在你的第一个剪辑中,你通过了
"\\\\.\\F:"
(AKA\\.\F:
一旦我们删除了C逃逸); 在您从命令行尝试的所有尝试中,您从未提供此路径,但分别为:
D
- 所以它试图在当前目录中打开一个名为D
的文件,但它没有找到它(错误2,又名ERROR_FILE_NOT_FOUND
);D:\
- 根目录,无法使用CreateFile
打开(错误3,又名ERROR_PATH_NOT_FOUND
),D:
- 驱动器D:上的当前目录,再次无法使用CreateFile
打开(错误5,又名ERROR_ACCESS_DENIED
);\D:
- 当前驱动器根目录中名为“D:”的文件,如果D:
不是有效文件名(错误123,又名ERROR_INVALID_NAME
),则无法创建该文件。要将驱动器作为设备打开, 必须使用
\\.\X:
path(其中X
是驱动器号); 你不能只是扔掉你心中的任何漂浮物,并希望它能起作用。 从命令行调用你的程序,通过"\\.\D:"
,它将正常工作。当然,如果你想让用户更简单,你可以只接受命令行上的驱动器号并编写一些代码来创建
CreateFile
所需的字符串。if(argc<1) { printf("Not enough arguments\n"); return 1; } const char *drive = argv[1]; char d = drive[0]; // accept both `d` and `d:` as argument for the drive if(!((d>='a' && d<='z') || (d>='A' && d<='Z')) || (drive[1]!=0 && drive[1]!=':') || drive[2]!=0) { printf("Invalid drive specifier: `%s`\n", drive); return 2; } char path[]="\\\\.\\X:"; path[4] = d; // now you can use path as argument to CreateFileA
接下来是原始答案,它仍然有效,但它解决了一个完全不同的问题,与OP正在经历的实际问题无关
你不能让
LPWSTR
指向一个char *
,特别是不要粗暴地LPWSTR
指针 -LPWSTR
一个指针只会让编译器闭嘴,它不会改变你指向的东西不是一个wchar_t
字符串的事实。 如果要将char *
传递给期望wchar_t *
的函数,则必须执行指向数据的实际转换。现在,您有几种可能的解决方案:
- 你可以使用
_wmain
直接接收命令行参数作为宽字符;- 您可以使用MultiByteToWideChar等函数将本地编码字符串转换为UTF-16字符串; 这可以封装在一个返回
std::wstring
的函数中;- 你可以调用API的ANSI版本并让它处理它; 几乎所有的Win32 API都有ANSI和Unicode版本,后缀为A和W(
CreateFile
只是一个扩展为CreateFileA
或CreateFileW
的宏,具体取决于_UNICODE
宏)。 因此,您可以使用CreateFileA
并按原样将其传递给它。最后两个解决方案并不是很好,因为使用本地编码字符串作为命令行参数会阻止程序使用任意Unicode字符打开文件。 OTOH,使用
wchar_t
几乎无处不在,因为它们“感染”了应用程序中几乎每个字符串处理的角落。 正确的(恕我直言)出路是在任何地方使用UTF-8,并在与操作系统交谈时动态转换; 看详情 。EDIT 2: i changed the CreateFile to CreateFileA , and this is the eroor codes it gives me (the drive D is a usb, its not a hard drive)
This is a completely different question, and has nothing to do with
wchar_t
.In your first snipped you passed
"\\\\.\\F:"
(AKA\\.\F:
once we remove the C escaping); in all your tries from the command line you never provided this path, but respectively:
D
- so it tried to open a file namedD
in the current directory, and it didn't find it (error 2, akaERROR_FILE_NOT_FOUND
);D:\
- the root directory, which cannot be opened withCreateFile
(error 3, akaERROR_PATH_NOT_FOUND
),D:
- the current directory on the drive D:, which again cannot be opened withCreateFile
(error 5, akaERROR_ACCESS_DENIED
);\D:
- a file named "D:" in the root of the current drive, which cannot be created given thatD:
is not a valid file name (error 123, akaERROR_INVALID_NAME
).To open a drive as a device, you must use the
\\.\X:
path (whereX
is the drive letter); you cannot just throw whatever floats in your mind and hope that it'll work. Call your program from the command line passing"\\.\D:"
and it'll work fine.Of course if you want to keep it simpler for the user you can accept just the drive letter on the command line and write some code to create the string required by
CreateFile
based on it.if(argc<1) { printf("Not enough arguments\n"); return 1; } const char *drive = argv[1]; char d = drive[0]; // accept both `d` and `d:` as argument for the drive if(!((d>='a' && d<='z') || (d>='A' && d<='Z')) || (drive[1]!=0 && drive[1]!=':') || drive[2]!=0) { printf("Invalid drive specifier: `%s`\n", drive); return 2; } char path[]="\\\\.\\X:"; path[4] = d; // now you can use path as argument to CreateFileA
What follows was the original answer, which is still valid but it addresses a completely different problem, unrelated to the actual problem OP is experiencing
You cannot make
LPWSTR
point to achar *
, especially not by brutally casting the pointer - casting a pointer just makes the compiler shut up, it doesn't change the fact that what you are pointing at is not awchar_t
string. If you want to pass achar *
to a function expecting awchar_t *
you have to perform an actual conversion of the pointed data.Now, you have several possible solutions:
- you can use
_wmain
and receive your command line arguments directly as wide characters;- you can convert your local-encoding strings to UTF-16 strings by using a function such as the MultiByteToWideChar; this can be encapsulated in a function returning a
std::wstring
;- you can just invoke the ANSI version of the API and let it deal with it; almost all Win32 APIs have both an ANSI and Unicode version, suffixed with A and W (
CreateFile
is just a macro that expands toCreateFileA
orCreateFileW
depending on the_UNICODE
macro). So, you can useCreateFileA
and pass it your string as-is.The last two solutions are not great because using local-encoding strings as command line arguments precludes your program from opening files using arbitrary Unicode characters. OTOH, using
wchar_t
almost everywhere is quite a dread, since they "infect" virtually every string-processing corner of your application. The correct (IMHO) way out is to use UTF-8 everywhere, and convert on the fly when talking to the operating systems; see here for details.
相关问答
更多-
LPWSTR字符串的连接(Concatenation of LPWSTR strings)[2022-01-31]
C ++方式: std::wstring mywstring(mystring); std::wstring concatted_stdstr = L"hello " + mywstring + L" blah"; LPCWSTR concatted = concatted_stdstr.c_str(); The C++ way: std::wstring mywstring(mystring); std::wstring concatted_stdstr = L"hello " + mywstring ... -
C ++ #define LPWSTR?(C++ #define LPWSTR?)[2022-12-07]
编辑2:我将CreateFile更改为CreateFileA,这是它给我的eroor代码(驱动器D是USB,它不是硬盘) 这是一个完全不同的问题,与wchar_t无关。 在你的第一个剪辑中,你通过了"\\\\.\\F:" (AKA \\.\F:一旦我们删除了C逃逸); 在您从命令行尝试的所有尝试中,您从未提供此路径,但分别为: D - 所以它试图在当前目录中打开一个名为D的文件,但它没有找到它(错误2,又名ERROR_FILE_NOT_FOUND ); D:\ - 根目录,无法使用CreateFile打开( ... -
该文件说: lgrui0_name 指向一个Unicode字符串的指针,指定用户所属的本地组的名称 您需要使用UNICODE方法(通常在Windows上标记为大写W)或者需要将其转换 : for (int i = 0; i
使用pInvoke将C样式的LPWSTR数组编组到托管字符串[](Marshalling C-style array of LPWSTR to managed string[] using pInvoke)[2021-10-06]
略有修改的代码,但签名是重要的。 此方法将字符串值(第三个参数)分配给传入的未初始化的out数组的第一个元素。 [DllImport("Dll1.Windows.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] public static extern void TestArrayOfStrings( [MarshalAs(UnmanagedType.LPArray, Arra ...您的程序配置为编译为unicode。 这就是为什么GetCurrentDirectory是GetCurrentDirectoryW,它需要一个LPWSTR ( wchar_t* )。 GetCurrentDirectoryW需要一个wchar_t而不是char数组。 您可以使用TCHAR来完成此操作,它像GetCurrentDirectory一样依赖于unicode设置并始终表示适当的字符类型。 不要忘记用L来预先设置'\0' ,以便使字符文字unicode也可以! Your program is conf ...不要转换。 使用wprintf代替printf : wprintf 请参阅说明如何使用它的示例 。 或者,你可以使用std::wcout作为: wchar_t *wstr1= L"string"; LPWSTR wstr2= L"string"; //same as above std::wcout << wstr1 << L", " << wstr2; 同样,使用为宽字符设计的函数,并忘记将wchar_t转换为char的想法,因为它可能会丢失数据。 看看这里处理宽字符的函数: Unicode在Vis ...C ++ 11 char16_t类型与wchar_t不同。 从理论上讲,你可以在char16_t*和char16_t*之间reinterpret_cast你的方式(Windows的wchar_t是16位)。 但实际上,Visual C ++ 10.0 - 我认为Visual C ++ 11.0 - 缺乏对u'A'或u"A"等Unicode文字的支持。 总结(我发现在SO上应该更好地明确所有结论): “在我的库中使用C ++ 11的u16string是否可以?” 当然,但不是作为wchar_t字符串的直接插件 ...LPWSTR是一个“宽”字符串,即Unicode。 PtrToStringUni可能会更好地为您服务。 此外,IntPtr确实有+运算符重载,你应该能够做IntPtr ptr = mystruct.items + (IntPtr.Size * x) LPWSTR is a 'wide' string, i.e., Unicode. PtrToStringUni will probably work better for you. Also, IntPtr does have the + operator o ...std::to_wstring更简单,但要指出代码中的问题,你从未创建过缓冲区 。 LPWSTR ret = L""; 使ret成为指向静态内存中保存的数组的指针。 此数组无法修改。 以下是使用std::wstring作为缓冲区来修复代码的一种方法: std::wstring IntToWstring(int value) { std::ostringstream convert; std::string out; convert << value; ou ...LPWSTR到wstring c ++(LPWSTR to wstring c++)[2022-07-17]
无需转换或复制。 std::wstring nnWString(MAX_PATH, 0); nnWString.resize(LoadStringW(hMod, id, &nnWString[0], nnWString.size()); 注意:您的原始代码会导致未定义的行为,因为它使用未初始化的指针进行写入。 肯定不是你想要的。 这是另一种变化: http://msmvps.com/blogs/gdicanio/archive/2010/01/05/stl-strings-loading-from-res ...相关文章
更多- rails save问题数据库表主键必须是id吗?
- hibernate id 生成策略及主要使用方法
- 有些困惑,大家帮忙看看一对多映射时save的一个问题,多谢了!!!
- Hadoop下远程调试Child子进程
- hibernate的级联删除
- 关于Hibernate级联数据表的存储问题(多对一)
- MongoDB _id和ObjectId详解
- 配置solr自动生成id
- solr required field: id
- js 通过td的id值 如何拿到tr的id值?
最新问答
更多- 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
- 如何通过引用返回对象?(How is returning an object by reference possible?)
- 矩阵如何存储在内存中?(How are matrices stored in memory?)
- 每个请求的Java新会话?(Java New Session For Each Request?)
- css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
- 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
- xcode语法颜色编码解释?(xcode syntax color coding explained?)
- 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
- 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
- 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
- 西安哪有PLC可控制编程的培训
- 在Entity Framework中选择基类(Select base class in Entity Framework)
- 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
- 电脑二级VF有什么用
- Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
- 金华英语角.
- 手机软件如何制作
- 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
- 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
- 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
- Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
- 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
- python的访问器方法有哪些
- DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
- 在Ruby中对组合进行排序(Sorting a combination in Ruby)
- 网站开发的流程?
- 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
- 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
- 透明度错误IE11(Transparency bug IE11)
- linux的基本操作命令。。。