我正在使用带有JPA 2.0的Spring 4.3.1并连接到MSSQL。我正在使用JpaRepository的保存方法来插入和更新数据。其中一个字段具有 nvarchar,可以包含拉丁语、中文等特殊字符。
另外,我在applicationContext-hibernate.xml中设置了以下JPA属性。
<prop key="hibernate.connection.CharSet">UTF-8</prop>
<prop key="hibernate.connection.useUnicode">true</prop>
<prop key="hibernate.connection.characterEncoding">UTF-8</prop>
当我保存数据时,所有特殊字符都保存为问号(??)。 建议的解决方案是在更新查询前面附加"N",以保持插入的特殊字符。但是,我在任何地方都看不到如何在 JpaRepository 的保存方法中附加"N"。有什么建议吗?
将字段声明为 byte[] 数组,如下所示。
@Column(name="[colName]", columnDefinition = "nvarchar", length=4000)
private byte[] colName;
在映射时,您必须使用 UTF-16 将 byte[] 转换为字符串,如下所示。 从数据库(映射):
byte[] eCodeData = dbData.getColName();
if(eCodeData != null){
uiData.setColName(new String(eCodeData, StandardCharsets.UTF_16));
}
到数据库:
String eCodeData = uiData.getColName();
if(eCodeData != null){
dbData.setColName(eCodeData.getBytes(StandardCharsets.UTF_16));
}
就是这样。这将发挥魔力。
实际上不必为字段定义 byte[] 数组,但
@Column(columnDefinition = "nvarchar(255)")
private String colName;
够了。
也许它可以帮助其他人,因为我在研究期间浏览了堆栈溢出中的所有文章。 我的应用程序(Java/Jboss/Hibernate/JPA/M$ SqlServer)运行良好,并且正确处理来自UI输入的字符串。 但是我也通过 EJB 将一些数据加载到数据库中。在这里,带有德语变音符号的字符串被损坏并映射错误。 *.java是用 UTF-8 正确编码的,所有工具都显示 UTF-8 编码。
我遵循了互联网/堆栈溢出中的所有建议。用
- 编码
- sendStringParametersAsUnicode=
- 扩展 SQLServerDialect
没有什么真正有帮助的。
最后我发现了问题所在。我是一个格拉德尔问题。 我正在调用javac编译器:
tasks.withType(JavaCompile) {
options.with {
fork = true
forkOptions.executable = "${jdk8base}/bin/javac"
}
}
在我的环境中,源代码没有解释为 UTF-8 编码,因此编译后的 *.class 被解释为拉丁语。EJB正在将拉丁语加载到DB(JPA)中。
溶液:
tasks.withType(JavaCompile) {
options.with {
encoding = 'UTF-8'
fork = true
forkOptions.executable = "${jdk8base}/bin/javac"
}
}
所以:@Column(columnDefinition = "nvarchar(255)") 就足够了。