The springAOP of pointcut using #annotation is not effective when applied to IbatisDAO - spring-aop

Annotation:
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface IbatisAnno {}
Aspect:
#Component
#Aspect
public class IbatisAsepct {
//not works
#Pointcut("#annotation(xxx.IbatisAnno)")
public void m(){}
//works
#Pointcut("execution(* xxx.xxDAO.*(..))")
public void m2(){}
#Before("m()")
public void testM(){
System.out.println("Before Method...............");
}
#Before("m2()")
public void testM2(){
System.out.println("Before Method2...............");
}
}
Target class:
#EnableAspectJAutoProxy()
public class IbatisOfferFeedDAO extends SqlMapClientDaoSupport implements OfferFeedDAO{
#IbatisAnno
public void xxx(){
this.getSqlMapClientTemplate().insert();
}
}
Aspect does not take effect when using #Pointcut("#annotation(xxx.IbatisAnno)"), but it works when using #Pointcut("execution(* xxx.xxDAO.*(..))").

Related

Proper way to handle prism navigation exception

I am using Prism Wpf 8.1.97, and DryIoc container.
In my scenario i have to navigate between two views, so I implemented the INavigationAware Interface provided by Prism Framework in my viewModels.
I call the IRegionManager RequestNavigate method to perform the navigation from the VMA to VMB.
Unfortunately, I forgot to register a IService dependency that is needed in the VMB Ctor, so when I perform the navigation process I get the exception in the navigation callback.
The IService interface
public interface IService
{
}
ViewModel A:
public class ViewAViewModel : BindableBase, INavigationAware
{
private readonly IRegionManager regionManager;
public ViewAViewModel(IRegionManager regionManager)
{
this.regionManager = regionManager;
}
public void OnNavigatedTo(NavigationContext navigationContext)
{
regionManager.TryRequestNavigate("ContentRegion", "ViewB", new NavigationParameters());
}
public bool IsNavigationTarget(NavigationContext navigationContext)
{
return true;
}
public void OnNavigatedFrom(NavigationContext navigationContext)
{
}
}
ViewModelB:
public class ViewBViewModel : BindableBase, INavigationAware
{
public ViewBViewModel(IService service)
{
}
public bool IsNavigationTarget(NavigationContext navigationContext)
{
return true;
}
public void OnNavigatedFrom(NavigationContext navigationContext)
{
}
public void OnNavigatedTo(NavigationContext navigationContext)
{
}
}
I created an extension method to keep it simple..
public static class IRegionManager_Extensions
{
public static void TryRequestNavigate(this IRegionManager regionManager, string regionName, string target, NavigationParameters navigationParameters)
{
regionManager.RequestNavigate(regionName, target, NavigationResult =>
{
if (NavigationResult.Result == false)
{
MessageBox.Show(NavigationResult.Error.InnerException.Message, "Navigation Exception", MessageBoxButton.OK, MessageBoxImage.Error);
}
}, navigationParameters);
}
}
Unfortunately what I get from the InnerException.Message is
ContainerException: code: Error.UnableToResolveFromRegisteredServices;
message: Unable to resolve Resolution root
Module1.ViewModels.ViewBViewModel from container without scope with
Rules with {TrackingDisposableTransients,
UseDynamicRegistrationsAsFallbackOnly, FuncAndLazyWithoutRegistration,
SelectLastRegisteredFactory} and without
{ThrowOnRegisteringDisposableTransient,
UseFastExpressionCompilerIfPlatformSupported} with
FactorySelector=SelectLastRegisteredFactory with
Made={FactoryMethod=ConstructorWithResolvableArguments} with normal
and dynamic registrations: (DefaultDynamicKey(0), {FactoryID=178,
ImplType=Module1.ViewModels.ViewBViewModel, Reuse=TransientReuse,
HasCondition})
without no reference to "IService"
I need to show that the navigation failed because IService implementation is not found in the container.
Is there a way to get the missing service Interface name from the exception?
Service name in the exception is null
Thanks.

sometimes my database does not update with the same code

my code in android studio and JAVA language has a problem with its database. I have a edittext in a fragment and I use it for update database. the database is initialized using Room library in activity and the DAO file is defined public and static in mainActivity, and use method DAO.update(photo) in a fragment, but sometimes when type in edittext it updates the field in database but sometimes not, I do not know why? can you please help me on it and do you have same experience?
related code in activity:
public class MainActivity extends AppCompatActivity {
public AppDB appDB;
public static AlbumDAO albumDAO;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
appDB= Room.databaseBuilder(this, AppDB.class, "db_App")
.allowMainThreadQueries()
.build();
albumDAO= appDB.getAlbumDAO();
and then I used the database initialized in main activity in this fragment:
public class PhotoFragment extends Fragment {
private Album album;
EditText title;
String inputTitle;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.album=getArguments().getParcelable("key");
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return LayoutInflater.from(getContext()).inflate(R.layout.fragment_photo,container,false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
title=view.findViewById(R.id.txt_postTitle);
title.setText(album.getTitle());
title.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
inputTitle=charSequence.toString();
}
#Override
public void afterTextChanged(Editable editable) {
album.setTitle(inputTitle);
albumDAO.updateAlbum(album);
}
});
}
and the albumDAO is:
#Dao
public interface AlbumDAO {
#Insert
long addAlbum(Album album);
#Query("SELECT * FROM tbl_album")
List<Album> getAllAlbums();
#Update
void updateAlbum(Album album);
#Delete
void deleteAlbum(Album album);
#Query("DELETE FROM tbl_album")
void deleteAllAlbum();
}
and the Album class is:
#Entity(tableName = "tbl_album")
public class Album implements Parcelable {
#PrimaryKey (autoGenerate = true)
private int id;
private String title;
public Album() {
}
protected Album(Parcel in) {
title = in.readString();
}
public static final Creator<Album> CREATOR = new Creator<Album>() {
#Override
public Album createFromParcel(Parcel in) {
return new Album(in);
}
#Override
public Album[] newArray(int size) {
return new Album[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(title);
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
In the overidden afterTextChanged method. You are updating the database and then changing the title in the album, so the database will not reflect the changed title.
Try using :-
#Override
public void afterTextChanged(Editable editable) {
album.setTitle(inputTitle); //<<<<< MOVED UP
albumDAO.updateAlbum(album);
}
You can also utilise the value (int) returned by the #Update annotated function, to see if anything has been updated by changing it to:-
#Update
int updateAlbum(Album album)
Then you could use something along the lines of:-
#Override
public void afterTextChanged(Editable editable) {
album.setTitle(inputTitle);
if (album.setTitle(inputTitle)> 0) {
.... do whatever here to indicate update was OK
} else {
.... do whatever here to indicate not updated
}
}

How to use mockito in ExchangeTestSupport

I have camel route as below
public class MainRouteBuilder extends RouteBuilder {
#Autowired
private CcsRouteCommonProperties commonProps;
/**
* {#inheritDoc}
*/
#Override
public void configure() throws Exception {
}
}
I have written test using ExchangeTestSupport as below
public class MainRouteBuilderTest extends ExchangeTestSupport {
/**
* {#inheritDoc}
*/
#Override
public RoutesBuilder createRouteBuilder() throws Exception {
}
#Test
public void shouldProcess() throws Exception {
}
}
I am trying to mock CcsRouteCommonProperties something like below
#Mock
private CcsRouteCommonProperties commonProps;
How to mock the above field using mockito(#RunWith(MockitoJUnitRunner.class))
Direct answer to your question would be to Use #InjectMocks on MainRouteBuilder and let Mockito inject an #Mock or #Spy of CcsRouteCommonProperties. I hope this short guide shall explain it for you.
Solution would be something like
#RunWith(MockitoJUnitRunner.class)
public class MainRouteBuilderTest extends ExchangeTestSupport {
#Mock
CcsRouteCommonProperties commonProps;
#InjectMocks
MainRouteBuilder routeBuilder;
#Override
public RoutesBuilder createRouteBuilder() throws Exception {
return routeBuilder;
}
#Test
public void shouldProcess() throws Exception {
when(commonProps.getSomething()).thenReturn(new Something());
}
}
However, if I am in your place, I'd avoid #Autowired magic and use clearly stated dependencies using constructor injection.
Route Builder
public class MainRouteBuilder extends RouteBuilder {
private CcsRouteCommonProperties commonProps;
public MainRouteBuilder( CcsRouteCommonProperties commonProps) {
this.commonProps = commonProps;
}
/**
* {#inheritDoc}
*/
#Override
public void configure() throws Exception {
}
}
Test
#RunWith(MockitoJUnitRunner.class)
public class MainRouteBuilderTest extends ExchangeTestSupport {
#Mock
CcsRouteCommonProperties commonProps;
#Override
public RoutesBuilder createRouteBuilder() throws Exception {
return new MainRouteBuilder(commonProps);
}
#Test
public void shouldProcess() throws Exception {
}
}

Execute aspect advice in same transaction context

I am trying to use Spring-AOP/AspectJ on the methods in a class annotated with #Transactional. So, I have two model DAO classes like this:
#Transactional
#Repository
public class ModelDAO {
public void save() {
}
}
#Transactional
#Repository
public class AnotherModelDAO {
public void save() {
}
}
And then an Aspect like:
#Aspect
public class ModelAspect {
#Around("publicMethod() && isModelClassSaveCalled()")
public Object doAspect(ProceedingJoinPoint joinPoint) throws Throwable {
joinPoint.proceed();
anotherModelDAO.save();
}
}
So, my question is: Is it possible to call model.save() and anotherModel.save() to be called in same transaction context through aspect as mentioned above?
Any help will be much appreciated.

MEF problem with import

I have problem with import shell-view-model to view-model class, I use MEF.
Shell-view-model :
namespace Spirit.ViewModels
{
using Caliburn.Micro;
using System.ComponentModel.Composition;
public interface IShellViewModel
{
void ShowLogOnView();
void ShowMessengerView();
}
[Export(typeof(IShellViewModel))]
public class ShellViewModel : Conductor<IScreen>, IShellViewModel
{
public ShellViewModel()
{
ShowLogOnView();
}
public void ShowLogOnView()
{
ActivateItem(new LogOnViewModel());
}
public void ShowMessengerView()
{
ActivateItem(new LogOnViewModel());
}
}
}
I need this class import in view-model class:
[Export]
public class LogOnViewModel : Screen, IDataErrorInfo
{
[Import]
private IShellViewModel _shellViewModel;
public void LogOn(string nick, string password)
{
IMessengerViewModel vm = IoC.Get<MessengerViewModel>();
_shellViewModel.ShowMessengerView();
}
}
Problem is after initialize is variable _shellViewModel null.
My bootstraper look like this:
public class MefBootStrapper : Bootstrapper<IShellViewModel>
{
}
MY SOLUTION:
I create interface assembly and refer this assembly in external service dll and also in wpf app.
In bootstraper I load this assembly with reflection:
var catalog =
new AggregateCatalog(
AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>());
catalog.Catalogs.Add(
new AssemblyCatalog(string.Format(
CultureInfo.InvariantCulture, "{0}{1}", System.IO.Directory.GetCurrentDirectory(), #"\Pokec_Toolkit.dll")));
_container = new CompositionContainer(catalog);
Than I create conductor class:
public interface IShellViewModel
{
void ShowLogOnView();
void ShowMessengerView();
}
[Export(typeof(IShellViewModel))]
public class ShellViewModel : Conductor<IScreen>, IShellViewModel
{
public ShellViewModel()
{
ShowLogOnView();
}
public void ShowLogOnView()
{
ActivateItem(IoC.Get<LogOnViewModel>());
}
public void ShowMessengerView()
{
ActivateItem(IoC.Get<MessengerViewModel>());
}
}
And in view-model I have this:
[Export]
public class LogOnViewModel : Screen, IDataErrorInfo, ILogOnViewModel
{
[Import]
private IShellViewModel _shellViewModel;
[Import]
private IPokecConnection _pokecConn;
//this method is bind on event click of button
public void LogOn(string nick, string password)
{
//SHOW NEW WIEW
_shellViewModel.ShowMessengerView();
}
}

Resources