[英]org.dozer.MappingProcessor - Field mapping error ByteArray
我有以下實體,DTO類和推土機映射文件。 我正在嘗試使用推土機映射將包含2個暗字節數組的休眠實體復制到新的DTO。 獲取java.lang.IllegalArgumentException:數組元素類型不匹配。
任何想法?
映射文件:
<mapping map-id="i" wildcard="false">
<class-a>com.csinfra.jdbmon.web.client.dto.Config.HostGroups.HostGroup.CheckGroup.Check.Type.MultiResult</class-a>
<class-b>com.csinfra.jdbmon.web.client.dto.MultiResultDTO</class-b>
<field>
<a>id</a>
<b>id</b>
</field>
<field>
<a>columns</a>
<b>columns</b>
</field>
</mapping>
實體類:
@Entity(name="multiResult")
@Table(name="multiResult")
public static class MultiResult implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@javax.persistence.Column(name = "id", unique = true, nullable = false)
private Long id;
@Lob
@javax.persistence.Column(name = "columns",length = 10000)
private byte[][] columns;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public byte[][] getColumns() {
return columns;
}
public void setColumns(byte[][] columns) {
this.columns = columns;
}
}
DTO類:
public class MultiResultDTO implements IsSerializable {
private Long id;
private byte[][] columns;
public MultiResultDTO(){}
public byte[][] getColumns() {
return columns;
}
public void setColumns(byte[][] columns) {
this.columns = columns;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
例外:
19165 ERROR org.dozer.MappingProcessor - Field mapping error -->
MapId: null
Type: null
Source parent class: com.csinfra.jdbmon.web.client.dto.Config$HostGroups$HostGroup$CheckGroup$Check$Type$MultiResult
Source field name: columns
Source field type: class [[B
Source field value: [[B@127a7396
Dest parent class: com.csinfra.jdbmon.web.client.dto.MultiResultDTO
Dest field name: columns
Dest field type: [[B
java.lang.IllegalArgumentException: array element type mismatch
at java.lang.reflect.Array.set(Native Method)
at org.dozer.MappingProcessor.addToPrimitiveArray(MappingProcessor.java:712)
at org.dozer.MappingProcessor.mapArrayToArray(MappingProcessor.java:629)
. . .
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
這是設計決定還是錯誤。 我在一個簡單的環境中將其復制並歸檔 。 看來,它可能修補代碼至少要支持多維數組(多維集合仍然不以這種方式工作),但我只做到了為理念,為構建一個全新的對象的“幸福路”的證明,省略目標對象可能已經具有非null字段的部分。 支持所有情況下需要做的工作量很大,這暗示僅支持一維集合和數組是一項設計決定。 但這只是我的觀點,我是第一次看到該代碼,也許我們有時會從經驗豐富的Dozer開發人員那里獲得更多信息。
如此說來,您可以通過為“ columns”參數(或實際上為任何1 d或2 d字節數組)編寫自定義轉換器,輕松解決特定情況。
IMO更長但更簡潔的方式(不依賴Dozer參與其中,因為這似乎有些不可靠 ):定義一個轉換器類
public class ByteArray2dConverter extends DozerConverter<byte[][], byte[][]> {
public ByteArray2dConverter() {
super(byte[][].class, byte[][].class);
}
public byte[][] convertTo(byte[][] source, byte[][] destination) {
if (source == null) {
return null;
}
byte[][] result = new byte[source.length][];
for (int i = 0; i < source.length; i++) {
byte[] element = source[i];
if (element != null) {
result[i] = Arrays.copyOf(element, element.length);
}
}
return result;
}
public byte[][] convertFrom(byte[][] source, byte[][] destination) {
return convertTo(source, destination);
}
}
...並將custom-converter
屬性添加到XML映射文件中的“列”字段:
<mapping map-id="i" wildcard="false">
<class-a>com.csinfra.jdbmon.web.client.dto.Config.HostGroups.HostGroup.CheckGroup.Check.Type.MultiResult</class-a>
<class-b>com.csinfra.jdbmon.web.client.dto.MultiResultDTO</class-b>
...
<field custom-converter="com.csinfra...ByteArray2dConverter">
<a>columns</a>
<b>columns</b>
</field>
</mapping>
另外,如果允許Dozer映射“頂層”數組並且僅將自定義轉換器用於第二層,則可以保存一些鍵入內容:定義一個轉換器
public class ByteArray1dConverter extends DozerConverter<byte[], byte[]> {
public ByteArray1dConverter() {
super(byte[].class, byte[].class);
}
public byte[] convertTo(byte[] source, byte[] destination) {
return source == null ? null : Arrays.copyOf(source, source.length);
}
public byte[] convertFrom(byte[] source, byte[] destination) {
return convertTo(source, destination);
}
}
...然后在XML映射中添加一個部分(與“映射”部分處於同一級別):
...
<configuration>
<custom-converters>
<converter
type="com.csinfra...ByteArray1dConverter">
<class-a>[B</class-a>
<class-b>[B</class-b>
</converter>
</custom-converters>
</configuration>
<mapping map-id="i" wildcard="false">
...
這樣,您就可以告訴Dozer在兩個字節數組之間的所有轉換中都使用轉換器(在前一種情況下您可以執行相同的操作,而不是在映射XML中的字段級別上定義自定義轉換器)。
還有一種選擇是使用對象的1維數組,每個對象具有1維字節數組,Dozer可以做到這一點。 類似於Column[] columns
,其中Column類具有一個字段byte[] columnBytes
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.