开发者

Hibernate is saving a completely new entity automatically(full stack of calls)

I have already asked this question two times, but I'm new to stackoverflow and it seems that I don't know the rules for formatting my example code in here. Now I've decided to give the full stack of the calls and I hope I can explain the situation because everything is so strange and I can't find the words to describe it. First I will give you the source of the classes that have something to do with the problem. My actual question is in the end of the page. The large piece of code is just in case, because I don't know what could be the explanation of my problem. Here is a service facade that gets calls from my flex applicati开发者_JS百科on.

public class ServiceFacade implements IAuthenticationService, IProfileService, ICampaignService {
    @Autowired
    private IAuthenticationService authenticationService;

    @Autowired
    private IProfileService profileService;

    @Autowired
    private ICampaignService campaignService;

    public void login(User user) throws AuthenticationException{
        authenticationService.login(user);
    }

    @Override
    public void logout() throws AuthenticationException {
        authenticationService.logout();
    }

    @Override
    public void sendForgottenPassword(String email) {
        authenticationService.sendForgottenPassword(email);
    }

    @Override
    public Profile getProfile(Long userId) {
        return profileService.getProfile(userId);
    }

    @Override
    public Profile updateProfile(Profile profile) {
        return profileService.updateProfile(profile);
    }

    @Override
    public Collection<String> getSocialConnectionsTypes(Long userId) {
        return profileService.getSocialConnectionsTypes(userId);
    }

    @Override
    public List<Email> findDuplicateEmails(Long profileId, List<Email> emails) {
        return profileService.findDuplicateEmails(profileId, emails);
    }

    @Override
    public Campaign getCampaign(Long campaignId) {
        return campaignService.getCampaign(campaignId);
    }

    @Override
    public Campaign updateCampaign(Campaign campaign) {
        return campaignService.updateCampaign(campaign);
    }

    @Override
    public void removeCampaign(Long campaignId) {
        campaignService.removeCampaign(campaignId);
    }

    @Override
    public void setPools(Long campaignId, Collection<Pool> pools) {
        campaignService.setPools(campaignId, pools);
    }

    @Override
    public void addPool(Long campaignId, Pool pool) {
        campaignService.addPool(campaignId, pool);
    }

    @Override
    public void removePool(Long campaignId, Pool pool) {
        campaignService.removePool(campaignId, pool);
    }

    @Override
    public List<Campaign> getCampaigns() {
        return campaignService.getCampaigns();
    }

    @Override
    public void updatePool(Long campaignId, Pool pool) {
        campaignService.updatePool(campaignId, pool);
    }
}

The method which is important for my question is the findDuplicateEmails method.

The profileService is implemented in the following class:

public class ProfileService implements IProfileService {
    @Autowired
    private IProfileManager profileManager;

    @Override
    public Profile getProfile(Long userId) {
        return profileManager.getProfile(userId);
    }

    @Override
    public Profile updateProfile(Profile profile){
        profileManager.updateProfile(profile);
        return profile;
    }

    @Override
    public Collection<String> getSocialConnectionsTypes(Long userId) {
        return profileManager.getSocialConnectionsTypes(userId);
    }

    @Override
    public List<Email> findDuplicateEmails(Long profileId, List<Email> emails) {
        return profileManager.findDuplicateEmails(profileId, emails);
    }
}

Again the important method is findDuplicateEmails

The implementation of the profileManager is the following class:

public class ProfileManager implements IProfileManager {
    @Autowired
    private IProfileDao profileDao;

    @Autowired
    private ISectionManager autoCompleteManager;

    @Autowired
    private IUserSecurityService userSecurityService;
    @Transactional
    public Profile getProfile(Long userId) {
        return profileDao.getProfileByUser(userId);
    }

    @Transactional
    public void updateProfile(final Profile profile) {

        List<Major> notApprovedMajors = extractNotApprovedMajors(profile);
        List<Degree> notApprovedDegrees = extractNotApprovedDegrees(profile);
        List<School> notApprovedSchools = extractNotApprovedSchools(profile);
        List<Language> notApprovedLanguages = extractNotApprovedLanguages(profile);
        List<Position> notApprovedPositions = extractNotApprovedPositions(profile);
        List<Company> notApprovedCompanies = extractNotApprovedCompanies(profile);
        List<Country> notApprovedCountries = extractNotApprovedCountries(profile);
        List<City> notApprovedCities = extractNotApprovedCities(profile);
        List<Certificate> notApprovedCertificates = extractNotApprovedCertificates(profile);

        autoCompleteManager.updateAll(notApprovedMajors);
        autoCompleteManager.updateAll(notApprovedDegrees);
        autoCompleteManager.updateAll(notApprovedSchools);
        autoCompleteManager.updateAll(notApprovedLanguages);
        autoCompleteManager.updateAll(notApprovedPositions);
        autoCompleteManager.updateAll(notApprovedCompanies);
        autoCompleteManager.updateAll(notApprovedCountries);
        autoCompleteManager.updateAll(notApprovedCities);
        autoCompleteManager.updateAll(notApprovedCertificates);

        profileDao.updateProfile(profile);
    }

    @Override
    public List<Email> findDuplicateEmails(Long profileId, List<Email> emails) {

        Profile persistedProfile = profileDao.findById(profileId);

        if (persistedProfile.getContact() == null)
        {
            persistedProfile.setContact(new Contact());
        }

        List<Email> resultEmails = new ArrayList<Email>();

        for (int i = 0; i < emails.size(); i++) {

            if ((!userSecurityService.guaranteeUniquePrincipal(emails.get(i)) &&
                    !isPersistedInThePersistentCollection(emails.get(i), persistedProfile.getContact().getEmails())) ||
                    isDuplicateInTheCurrentCollection(emails.get(i), emails, i + 1)) {
                resultEmails.add(emails.get(i));
            }
    }

        return resultEmails;
    }

    private boolean isDuplicateInTheCurrentCollection(Email emailToCheck, List<Email> emails, int index)
    {

        for (int i = index ; i < emails.size(); i ++) {
            if (emails.get(i).getEmailAddress().equals(emailToCheck.getEmailAddress())) {
                return true;
            }
        }

        return false;
    }

    private boolean isPersistedInThePersistentCollection(Email emailToCheck, Collection<Email> emails)
    {
        if (emails == null) {
            return false;
        }
        for (Email persistedEmail : emails) {
            if (persistedEmail.getEmailAddress().equalsIgnoreCase(emailToCheck.getEmailAddress())) {
                return true;
            }
        }

        return false;
    }
}

Again the important method is the method findDuplicateEmails

Now, after this short background, here is my problem:

I am using Hibernate with spring's HibernateTemplate. I found out that in the method findDuplicateEmails, some completely new entities which come form the flex application gets saved automatically. This was very strange and during the debbugging I found out that even if I change the method findDuplicateEmails in the ProfileManager so it looks like:

 @Override
 public List<Email> findDuplicateEmails(Long profileId, List<Email> emails) {   
     Email email = new Email();
     return null;
 }

the entity email gets saved automatically. I also found out that if the identifier of the entity is not "email", but something else, like "newEmail", or "email1", or something, there is no problem and the entity gets persisted if and only if I make it persistent. This problem exists only in this class and finally, this problem shows up only for the Email. I mean that if I have Phone phone = new Phone(); the entity phone gets persisted only when I wish.

The flex application first checks that the entered from the user emails are unique, and then after some user interaction calls the method updateProfile() if the entered data is valid.


I would download Hibernate sources and start debugging, you will either find a bug in Hibernate (happens) or in your code, as this is one weird behavior. This is an advice I got once, and was the fastest, most educating way to get to the root.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜