Spring Framework/Hibernate not picking up redefined classes by ByteBuddy
Hi,
I am trying to integrate ByteBuddy with a Spring project that uses spring-data-jpa and hibernate as it's dependency. I am trying to dynamically annotate a field in the data model with the @Transient annotation from javax.persistence.Transient during runtime. The idea is I would like to annotate the field in the data model based on some condition during runtime. Here is how the code looks:
The Data Model
@Entity
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "SOME_TABLE", schema = "someschema")
public class BubbleTea {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String flavour;
private String type; // Add transient dynamically
private BigDecimal price;
}
Wrapper for @Transient Annotation needed by ByteBuddy
public class TransientImpl implements Transient {
@Override
public Class<? extends Annotation> annotationType() {
return Transient.class;
}
}
The Utility Class to Annotate the field with Transient
@Component
public class BubbleTeaUtility {
public void addTransient() {
ByteBuddyAgent.install();
new ByteBuddy()
.redefine(BubbleTea.class)
.field(named("type"))
.annotateField(new TransientImpl())
.make()
.load(BubbleTea.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
}
}
The Service class using the utility to inject Transient dynamically based on some condition
@RequiredArgsConstructor
@Service
@Slf4j
public class BubbleTeaService {
private final BubbleTeaRepository bubbleTeaRepository;
private final BubbleTeaUtility bubbleTeaUtility;
public List<BubbleTea> getAllBubbleTeaByFlavour(String flavour) {
return bubbleTeaRepository.findByFlavour(flavour);
}
public BubbleTea addBubbleTea(BubbleTea bubbleTea) {
if (some condition is true) {
bubbleTeaUtility.addTransient();
}
return bubbleTeaRepository.save(bubbleTea);
}
}
I have logged out the annotations after the addTransient() method is called and bytebuddy is adding the @Transient annotation successfully. The problem is Hibernate is not picking up the modified classes with the annotation. How do I let Hibernate/Spring pick up the transformed classes with the newly added annotation?
Thank you
I assume that those frameworks scan the class path via persisted class files. I am not sure if there is a better way to alter the implicit configuration, but I would guess that code manipulation would need to be applied during build-time for this to work. Byte Buddy offers a build-time plugin for doing this.