Heat olive oil and 1 tablespoon butter in a large skillet over medium-high heat. When the butter has melted, add onion and season with salt and pepper. Stir in two tablespoons water, cover pot, and cook for several minutes, until onions soften slightly and begin to release their liquid. Remove lid, reduce heat to medium-low, and continue cooking for about 30 minutes, stirring occasionally, until the onions are very tender. Increase heat to medium-high and cook, stirring frequently, for about 5 more minutes, until the onions are golden and beginning to fall apart.
Meanwhile, melt remaining butter in a large sauce pan. Add flour and cook over medium-low heat for 3 minutes, whisking constantly until mixture turns a pale nutty brown. Slowly add milk while whisking, taking care as the steam will be very hot. Mix in paprika and onions.
Working carefully, use a stick blender to puree the onions into the sauce (if you don't have a stick blender, whirl onions in a food processor before adding). Add bay leaf and simmer for 15 minutes.
Off-heat, add 4 cups of the grated cheese to milk mixture, stirring until melted. Remove bay leaf. Stir in pasta and chopped ham. Season with salt and pepper.
Transfer mixture to a greased 9 by 13-inch casserole dish. Top with remaining cheese and bread crumbs. Bake in an oven preheated to 350° F until bubbly, about 30 minutes. Let sit for 5 to 10 minutes before serving.