AntonSaburov, именно! Если юзать энтити менеджер, то события легко перехватываются. Эх, генерация ключа происходит после перехвата события.
ПС В общем, сделал свою реализацию перехвата генерации ключа:
| Код | @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface PostGenerate { }
public class UUIDGenerator implements IdentifierGenerator, Configurable { private Object postGenerateInstance; // Инстанс листенера private List<Method> postGenerateMethods = new ArrayList<Method>(); // Колбек методы private boolean insideEntity; // Листенер - сам энтити
static private final Class<?> KEY_CLASS = String.class;
@Override public Serializable generate(SessionImplementor session, Object obj) { UUID uuid = UUID.randomUUID(); String result = uuid.toString().replaceAll("-", "");
if (insideEntity) { postGenerateInstance = obj; } // Вызов колбеков if (postGenerateInstance != null && postGenerateMethods != null) { for (Method method : postGenerateMethods) { try { method.setAccessible(true); if (insideEntity) { method.invoke(postGenerateInstance, new Object[] { result }); } else { method.invoke(postGenerateInstance, new Object[] { obj, result }); } } catch (Exception ex) { ex.printStackTrace(); } } }
return result; }
@Override public void configure(Type type, Properties params, Dialect d) throws MappingException { postGenerateInstance = null; postGenerateMethods.clear();
try { Class<?> entityClass = Class.forName(params.get("entity_name").toString()); // Класс энтити, задан в пропертях Class<?> postGenerateClass = entityClass; // По дефолту листенер - сам энтити
Object postGenerateValue = params.get("post-generate"); // Получаем класс листенера из параметра if (postGenerateValue != null) { String postGenerateClassName = postGenerateValue.toString(); postGenerateClass = Class.forName(postGenerateClassName); } insideEntity = (entityClass == postGenerateClass); if (!insideEntity) { // Листенер должен иметь конструктор без параметров postGenerateInstance = postGenerateClass.newInstance(); } // Ищем колбеки for (Method method : postGenerateClass.getDeclaredMethods()) { method.setAccessible(true); if (isMethodSuitable(postGenerateClass, entityClass, method)) { postGenerateMethods.add(method); } } } catch (Exception e) { e.printStackTrace(); } }
private boolean isMethodSuitable(Class<?> listenerClass, Class<?> entityClass, Method listenerMethod) { if (!listenerMethod.isAnnotationPresent(PostGenerate.class)) { // Выбираем аннотированные методы return false; }
Class<?>[] parameterTypes = listenerMethod.getParameterTypes(); // У метода должны быть либо 2 параметра: энтити и ключ (для случая отдельного класса колбека), // либо 1 - ключ (для случая колбека внутри энтити) return (insideEntity && parameterTypes.length == 1 && parameterTypes[0].isAssignableFrom(KEY_CLASS) || !insideEntity && parameterTypes.length == 2 && parameterTypes[0].isAssignableFrom(entityClass) && parameterTypes[1].isAssignableFrom(KEY_CLASS)); } }
// 1 Колбек внутри энтити @Entity @Table(name = "test") public class TestEntity { @Id @GeneratedValue(generator = "uuid_gen") @GenericGenerator(name = "uuid_gen", strategy = "ru.test.hiber.entities.UUIDGenerator", parameters = { @Parameter(name = "post-generate", value = "ru.test.hiber.entities.TestEntity") // Опционально }) @Column(name = "id", length = 32, nullable = false, unique = true) private String id; @Column(name = "data", length = 100, nullable = false) private String data;
// Get & Set @PostGenerate public void generatedKey(String key) { // Ключ сгенерен, но не записан в энтити } }
// 2 Колбек в отдельном классе @Entity @Table(name = "test") public class TestEntity { @Id @GeneratedValue(generator = "uuid_gen") @GenericGenerator(name = "uuid_gen", strategy = "ru.test.hiber.entities.UUIDGenerator", parameters = { @Parameter(name = "post-generate", value = "ru.test.hiber.entities.TestEntityListener") }) @Column(name = "id", length = 32, nullable = false, unique = true) private String id; @Column(name = "data", length = 100, nullable = false) private String data;
// Get & Set }
public class TestEntityListener { @PostGenerate public void postGen(TestEntity entity, String key) { // Ключ сгенерен, но не записан в энтити } }
|
|