tr
с помощью .closest()
code
с помощью .attr()
tr
, имеющие одинаковые code
, используя атрибут , равный селектору . .index()
Пример:
$("input[type='text']").change(function() {
var $parent = $(this).closest("tr");
var code = $parent.attr("code");
var $codeRows = $(this).closest("table").find("tr[code='" + code + "']");
var index = $codeRows.index($parent);
console.log(index);
});
]
Jorge I found one solution on http://forums.sun.com/thread.jspa?threadID=518416 which works.
Create the below class in your project. Whereever you creating object of ObjectInputStream, use DecompressibleInputStream instead and it deserializes the old object with the new version Id class.
public class DecompressibleInputStream extends ObjectInputStream {
public DecompressibleInputStream(InputStream in) throws IOException {
super(in);
}
protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
ObjectStreamClass resultClassDescriptor = super.readClassDescriptor(); // initially streams descriptor
Class localClass = Class.forName(resultClassDescriptor.getName()); // the class in the local JVM that this descriptor represents.
if (localClass == null) {
System.out.println("No local class for " + resultClassDescriptor.getName());
return resultClassDescriptor;
}
ObjectStreamClass localClassDescriptor = ObjectStreamClass.lookup(localClass);
if (localClassDescriptor != null) { // only if class implements serializable
final long localSUID = localClassDescriptor.getSerialVersionUID();
final long streamSUID = resultClassDescriptor.getSerialVersionUID();
if (streamSUID != localSUID) { // check for serialVersionUID mismatch.
final StringBuffer s = new StringBuffer("Overriding serialized class version mismatch: ");
s.append("local serialVersionUID = ").append(localSUID);
s.append(" stream serialVersionUID = ").append(streamSUID);
Exception e = new InvalidClassException(s.toString());
System.out.println("Potentially Fatal Deserialization Operation. " + e);
resultClassDescriptor = localClassDescriptor; // Use local class descriptor for deserialization
}
}
return resultClassDescriptor;
}
}
Если в базе данных хранится несколько версий класса, может быть довольно сложно десериализовать и обновить их все до согласованного формата сериализации за один проход.
Если возможно, вы можете изменить таблицу с помощью столбца, чтобы указать, был ли обработан сериализованный объект. Затем выполните проходы по таблице для каждого serialVersionUID
, где вы попытаетесь обработать любые объекты, с которыми еще не работали. Вы можете перехватить исключение InvalidClassException
и перейти к следующей записи, если ваш модуль обновления обнаружит сериализованный объект, который он не обрабатывает, записав номер версии, чтобы вы могли сделать еще один проход.
Это немного утомительно, но очень просто.
Сериализация Java имеет несколько очень полезных функций для поддержки эволюции классов. Тем не менее, вы должны знать, что вы делаете. Может случиться так, что все объекты на самом деле имеют одинаковые данные, но не было уделено внимания поддержанию идентификатора версии.
Вы можете продолжать использовать сериализацию, когда все объекты обновлены до одной и той же версии. Просто будьте осторожны, когда вы добавляете в класс новые поля, которые имеют смысл с их значениями по умолчанию (булевы значения равны false, объекты равны нулю, целые числа равны нулю и т. Д.).
Вы сможете обойти проблему, переопределив ObjectInputStream.readClassDescriptor
.
Использование XMLEncoder
на самом деле не поможет с миграцией версий, так как правила совместимости во многом совпадают. На самом деле, вероятно, следует сохранять объект в реляционной форме с помощью инструмента ORM.
Вероятно, разные serialVersionUID
произошли из-за различных синтетических членов, генерируемых javac. Отправьте предупреждения и вставьте serialVersionUID
в.
Я могу что-то упустить, но это звучит так, как будто вы пытаетесь сделать что-то более сложное, чем необходимо. Что произойдет, если:
(a) вы берете текущее определение класса (т.е. исходный код) и жестко кодируете его серийный UID к старому (или одному из старых), а затем используете это определение класса для десериализации сериализованные экземпляры?
(б) в байтовом потоке, который вы читаете, вы заменяете старые серийные UID новыми, прежде чем оборачивать их ObjectInputStream?
ОК, просто чтобы уточнить (б). Так, например, если у меня есть маленький класс, подобный этому:
public static class MyClass implements Serializable {
static final long serialVersionUID = 0x1122334455667788L;
private int myField = 0xff;
}
, то когда данные сериализуются, это выглядит примерно так:
ACED000573720011746573742E546573 ’..sr..test.Tes
74244D79436C61737311223344556677 t$MyClass."3DUfw
880200014900076D794669656C647870 ?...I..myFieldxp
000000FF ...ÿ
Каждая строка составляет 16 байтов, а каждый байт - 2 шестнадцатеричных цифры. Если вы посмотрите внимательно, во второй строке, 9 байтов (18 цифр), вы увидите, что начинается серийный идентификатор версии (1122 ...). Таким образом, в наших данных здесь (ваши будут немного отличаться), смещение идентификатора серийной версии составляет 16 + 9 = 25 (или 0x19 в шестнадцатеричном формате). Поэтому, прежде чем я начну десериализацию, если я захочу изменить идентификатор этой последовательной версии на что-то другое, мне нужно записать свой новый номер со смещением 25:
byte[] bytes = ... serialised data ...
ByteBuffer bb = ByteBuffer.wrap(bytes);
bb.putLong(25, newSerialVersionUID);
, тогда я просто продолжу как обычно:
ObjectInputStream oin = new ObjectInputStream(new ByteArrayInputStream(bytes));
MyClass obj = (MyClass) oin.readObject();