JPA java.util.ConcurrentModificationException on @manytomany List

I just had a java.util.ConcurrentModificationException when updating a List with JPA. Below the code which caused it, the required fix and some attention points.

Beurs.java

@Entity
@Table(name = "Beurs")
public class Beurs implements Serializable {
	private static final long serialVersionUID = -6250201709027758975L;

    @Id
	@Column(name = "beurscode", unique = true, nullable = false)
    private Long beurscode;

    private String beursnaam;

    private Integer iexFondsCode;

    private String iexFondsnaam;

    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable(name = "BeursFonds"  , joinColumns = { @JoinColumn(name = "beurs_beurscode", nullable = false, updatable = true) }
                                    , inverseJoinColumns = { @JoinColumn(name = "fonds_fondscode", nullable = false, updatable = true) })
	private List<Fonds> fondsen;

Fonds.java

@Entity
@Table(name = "Fonds")
public class Fonds implements Serializable {
	private static final long serialVersionUID = 4655056015858729584L;

	@Id
	@Column(name = "fondscode")
	private Long fondscode;

	@ManyToMany(mappedBy = "fondsen", fetch=FetchType.EAGER, cascade = CascadeType.ALL)
	private List<Beurs> beurzen;

The following code caused the exception, since while iterating over the List it is tried to update an entry of the same List. On some fora it is advised to use a ListIterator and call the add() and remove() functions on these.

	public void store(Fonds fonds) {
        List<Beurs> beurzen = fonds.getBeurzen();
        for(Beurs beurs: beurzen) {
            Beurs beursRepo = entityManager.find(Beurs.class, beurs.getBeurscode());

            beursRepo.getFondsen().add(fonds);
            entityManager.merge(beursRepo);
        }
	}

But since i also want an easy way to update existing objects in the array, I wrote the following code. First it updates the child [Fonds], then throws away all related entries in the jointable [if any] and then inserts the entries to the jointable.

Note that no update is being done on the parent [Beurs], so this one might be outdated on the first level cache. Especially the entries of the Fonds object. So in order to prevent first level cache issues, a flush() and a refresh() are done.

        entityManager.merge(fonds);

        // reset the manytomany
            beursRepository.deleteBeursFondsByFonds(fonds.getFondscode());

            for(Beurs beurs: fonds.getBeurzen()) {
                beursRepository.store(new BeursFonds(beurs.getBeurscode(), fonds.getFondscode()));

                Beurs beursRepo = entityManager.find(Beurs.class, beurs.getBeurscode());

                entityManager.flush();
                entityManager.refresh(beursRepo);
            }

Finally, the original exception. Which we just fixed.

java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
	at java.util.ArrayList$Itr.next(ArrayList.java:831)
	at org.hibernate.collection.AbstractPersistentCollection$IteratorProxy.next(AbstractPersistentCollection.java:580)
	at com.gjdb.tradetracker.repository.HibernateFondsRepository.store(HibernateFondsRepository.java:33)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
	at com.sun.proxy.$Proxy34.store(Unknown Source)

Galaxy Tab 2 Android 4.0.4 apps not updating and play store crashing

Just had some issues updating apps on my Galaxy Tab 2 [Android version 4.0.4].

There where more then 20 apps which required updating, but the Play store simply kept crashing.

Solution was to clear caches and buffer of the “Downloadmanager” and “Downloads” apps. Follow the following steps to do this:

1: Open settings (instelling in dutch)
2: Select “applications” (applicaties in dutch)
3: Select “all” / “alles”
4: Scroll down to “Downloadmanager” and “Downloads” (as in below screenshot)
Screenshot_2013-10-20-12-01-49
5: Select “clear caches” (buffer leegmaken) and “clear data” (gegevens wissen) for both apps
Screenshot_2013-10-20-12-02-08

After this updates got installed again as proven by these screenshots.

MAC OS X && [ERROR] Failed to execute goal org.apache.maven.plugins:maven-javadoc-plugin:2.9:jar (attach-javadocs) on project sonar-enforcer-rules-repository: MavenReportException: Error while creating archive: Unable to find javadoc command: The environment variable JAVA_HOME is not correctly set. -> [Help 1]

I just had this error while trying to perform maven release:

“[ERROR] Failed to execute goal org.apache.maven.plugins:maven-javadoc-plugin:2.9:jar (attach-javadocs) on project sonar-enforcer-rules-repository: MavenReportException: Error while creating archive: Unable to find javadoc command: The environment variable JAVA_HOME is not correctly set. -> [Help 1]”

How to fix? Simply:

1) Verify if the JAVA_HOME is really empty
MacBook-Pro-van-Geert:sonar-enforcer-rules-repository GJDB$ echo $JAVA_HOME

2) If empty: set it with the following command
MacBook-Pro-van-Geert:sonar-enforcer-rules-repository GJDB$ export JAVA_HOME=$(/usr/libexec/java_home)

3) Verify it has been set
MacBook-Pro-van-Geert:sonar-enforcer-rules-repository GJDB$ echo $JAVA_HOME
/Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home

javadoc-java-home-macosx

Webkit’s XSS Auditor explained and current exploits

Webkit is a open source browser engine used by Safari and Chrome. To prevent cross site scripting attacks (number 3 in this years in the security vulnerabilities list of OWASP), Webkit filters all the web traffic with a auditor.

This auditor, called the XSS auditor, can be looked up online: https://github.com/WebKit/webkit/blob/master/Source/WebCore/html/parser/XSSAuditor.cpp

What does it do?
It prevents cross site scripting (XSS) by replacing malicious scripts with an empty script, so ” <script> </script> “.

As an example, we have our insecure web application.
Schermafbeelding 2013-06-16 om 19.29.15

Which has a simple input value:
Schermafbeelding 2013-06-16 om 19.29.23

When inserted a malicious XSS value into a input field, like ” /><script>pay /* test */ &;lt/script></br ”
Schermafbeelding 2013-06-16 om 19.29.40

Then we see that after submitting the page, the malicious script has been removed.
Schermafbeelding 2013-06-16 om 19.29.59

But wait! There are exploits.
It is good to know that the auditor doesn’t reflect all possible output contexts, like in JSP:

<script type="text/javascript">
    var a = "<%= request.getParameter("a") %>";
    document.write("<text>Welcome "+ a + "</text>");
</script>

When this code is called as follows in our insecure web application

http://localhost:8081/insecure-web/noHtmlEscaping?a=2%22;%20alert(document.cookie);%20var%20a=%221

Then we get to see our session cookie!
Schermafbeelding 2013-06-16 om 19.41.02

JPA 2 @ManyToMany java.sql.BatchUpdateException: Field ‘id’ doesn’t have a default value

Required: having a ManyToMany relation with JPA. Underlying ORM framework I use is Hibernate, but that is irrelevant here since JPA abstracts this.

The Entities
For a @ManyToMany we need two entities. Here we have a entity ‘Beurs’, which owns a collection of ‘Fonds’.

Beurs:

@Entity
@Table(name = “Beurs”)
public class Beurs implements Serializable {
private static final long serialVersionUID = -6250201709027758975L;

@Id
@Column(name = “beurscode”, unique = true, nullable = false)
private Long beurscode;
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = “BeursFonds” , joinColumns = { @JoinColumn(name = “beurs_beurscode”, nullable = false, updatable = true) }
, inverseJoinColumns = { @JoinColumn(name = “fonds_fondscode”, nullable = false, updatable = true) })
private List fondsen;

Fonds:

@Entity
@Table(name = “Fonds”)
public class Fonds implements Serializable {
private static final long serialVersionUID = 4655056015858729584L;

@Id
@Column(name = “fondscode”)
private Long fondscode;

@ManyToMany(mappedBy = “fondsen”, fetch=FetchType.EAGER, cascade = CascadeType.ALL)
private List beurzen;

The Join Entity

@Entity
@Table(name = “BeursFonds”)
public class BeursFonds implements Serializable {

@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;

@Column(name = “beurs_beurscode”)
private Long beurscode;

@Column(name = “fonds_fondscode”)
private Long fondscode;

public BeursFonds() {
// default constructor for jpa
}

public BeursFonds(Long beurscode, Long fondscode) {
this.beurscode = beurscode;
this.fondscode = fondscode;
}

The entitymanager

public void store(Fonds fonds) {
List beurzen = fonds.getBeurzen();
for(Beurs beurs: beurzen) {
Beurs beursRepo = entityManager.find(Beurs.class, beurs.getBeurscode());

beursRepo.getFondsen().add(fonds);
entityManager.merge(beursRepo);
}
}

I have the ‘hibernate.hbm2ddl.auto’ set to value ‘update’, so when starting the webapplication with the new entities, these are auto generated. When you generated these tables by hand you might get the following exception. Solution: recreate the tables.

Caused by:
java.sql.BatchUpdateException: Field ‘id’ doesn’t have a default value
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:2007)
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1443)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.BatchingBatcher.addToBatch(BatchingBatcher.java:56)
at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1207)